diff --git a/CHANGELOG.md b/CHANGELOG.md index 63a9bba72..a0cce8463 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## **[Unreleased]** +## 0.14.1 - 2020-02-24 + +- [#1245](https://github.com/wasmerio/wasmer/pull/1245) Use Ubuntu 16.04 in CI so that we use an earlier version of GLIBC. +- [#1234](https://github.com/wasmerio/wasmer/pull/1234) Check for unused excluded spectest failures. +- [#1232](https://github.com/wasmerio/wasmer/pull/1232) `wasmer-interface-types` has a WAT decoder. + ## 0.14.0 - 2020-02-20 - [#1233](https://github.com/wasmerio/wasmer/pull/1233) Improved Wasmer C API release artifacts. diff --git a/Cargo.lock b/Cargo.lock index 69b3f3f80..4a8fe04ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -227,45 +227,46 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "cranelift-bforest" -version = "0.52.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56aa72ef104c5d634f2f9e84ef2c47e116c1d185fae13f196b97ca84b0a514f1" +checksum = "45a9c21f8042b9857bda93f6c1910b9f9f24100187a3d3d52f214a34e3dc5818" dependencies = [ - "cranelift-entity", + "cranelift-entity 0.59.0", ] [[package]] name = "cranelift-codegen" -version = "0.52.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460b9d20793543599308d22f5a1172c196e63a780c4e9aacb0b3f4f63d63ffe1" +checksum = "7853f77a6e4a33c67a69c40f5e1bb982bd2dc5c4a22e17e67b65bbccf9b33b2e" dependencies = [ "byteorder", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", - "cranelift-entity", + "cranelift-entity 0.59.0", + "gimli", "log", "smallvec 1.2.0", - "target-lexicon", + "target-lexicon 0.10.0", "thiserror", ] [[package]] name = "cranelift-codegen-meta" -version = "0.52.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc70e4e8ccebd53a4f925147def857c9e9f7fe0fdbef4bb645a420473e012f50" +checksum = "084cd6d5fb0d1da28acd72c199471bfb09acc703ec8f3bf07b1699584272a3b9" dependencies = [ "cranelift-codegen-shared", - "cranelift-entity", + "cranelift-entity 0.59.0", ] [[package]] name = "cranelift-codegen-shared" -version = "0.52.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3992000be4d18df0fe332b7c42c120de896e8ec54cd7b6cfa050910a8c9f6e2f" +checksum = "701b599783305a58c25027a4d73f2d6b599b2d8ef3f26677275f480b4d51e05d" [[package]] name = "cranelift-entity" @@ -274,14 +275,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "722957e05064d97a3157bf0976deed0f3e8ee4f8a4ce167a7c724ca63a4e8bd9" [[package]] -name = "cranelift-native" -version = "0.52.0" +name = "cranelift-entity" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21398a0bc6ba389ea86964ac4a495426dd61080f2ddd306184777a8560fe9976" +checksum = "b88e792b28e1ebbc0187b72ba5ba880dad083abe9231a99d19604d10c9e73f38" + +[[package]] +name = "cranelift-native" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32daf082da21c0c05d93394ff4842c2ab7c4991b1f3186a1d952f8ac660edd0b" dependencies = [ "cranelift-codegen", "raw-cpuid", - "target-lexicon", + "target-lexicon 0.10.0", ] [[package]] @@ -491,7 +498,7 @@ dependencies = [ "log", "scroll 0.10.1", "string-interner", - "target-lexicon", + "target-lexicon 0.9.0", "thiserror", ] @@ -633,9 +640,9 @@ dependencies = [ [[package]] name = "hex" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cdda6bf525062a0c9e8f14ee2b37935c86b8efb6c8b69b3c83dfb518a914af" +checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" [[package]] name = "indexmap" @@ -718,6 +725,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "leb128" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" + [[package]] name = "lexical-core" version = "0.4.6" @@ -733,9 +746,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.66" +version = "0.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" +checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" [[package]] name = "llvm-sys" @@ -1598,6 +1611,12 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f4c118a7a38378f305a9e111fcb2f7f838c0be324bfb31a77ea04f7f6e684b4" +[[package]] +name = "target-lexicon" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d" + [[package]] name = "tempfile" version = "3.1.0" @@ -1799,18 +1818,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86840eccceaf682e29be7810dcae5785b9c3b0349ce44d3eaecd9e50f893aee0" dependencies = [ "anyhow", - "cranelift-entity", + "cranelift-entity 0.52.0", "faerie", "gimli", "more-asserts", - "target-lexicon", + "target-lexicon 0.9.0", "thiserror", "wasmparser 0.39.3", ] [[package]] name = "wasmer" -version = "0.14.0" +version = "0.14.1" dependencies = [ "atty", "byteorder", @@ -1841,11 +1860,11 @@ dependencies = [ [[package]] name = "wasmer-clif-backend" -version = "0.14.0" +version = "0.14.1" dependencies = [ "byteorder", "cranelift-codegen", - "cranelift-entity", + "cranelift-entity 0.59.0", "cranelift-native", "libc", "nix", @@ -1854,52 +1873,52 @@ dependencies = [ "serde-bench", "serde_bytes", "serde_derive", - "target-lexicon", + "target-lexicon 0.10.0", "wasm-debug", "wasmer-clif-fork-frontend", "wasmer-clif-fork-wasm", "wasmer-runtime-core", "wasmer-win-exception-handler", - "wasmparser 0.45.2", + "wasmparser 0.51.3", "winapi", ] [[package]] name = "wasmer-clif-fork-frontend" -version = "0.52.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2e13201ef9ef527ad30a6bf1b08e3e024a40cf2731f393d80375dc88506207" +checksum = "c23f2824f354a00a77e4b040eef6e1d4c595a8a3e9013bad65199cc8dade9a5a" dependencies = [ "cranelift-codegen", "log", "smallvec 1.2.0", - "target-lexicon", + "target-lexicon 0.10.0", ] [[package]] name = "wasmer-clif-fork-wasm" -version = "0.52.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8b09302cc4fdc4efc03823cb3e1880b0fde578ba43f27ddd212811cb28c1530" +checksum = "a35e21d3aebc51cc6ebc0e830cf8458a9891c3482fb3c65ad18d408102929ae5" dependencies = [ "cranelift-codegen", - "cranelift-entity", + "cranelift-entity 0.59.0", "log", "thiserror", "wasmer-clif-fork-frontend", - "wasmparser 0.45.2", + "wasmparser 0.51.3", ] [[package]] name = "wasmer-dev-utils" -version = "0.14.0" +version = "0.14.1" dependencies = [ "libc", ] [[package]] name = "wasmer-emscripten" -version = "0.14.0" +version = "0.14.1" dependencies = [ "byteorder", "getrandom", @@ -1912,7 +1931,7 @@ dependencies = [ [[package]] name = "wasmer-emscripten-tests" -version = "0.14.0" +version = "0.14.1" dependencies = [ "glob 0.3.0", "wabt", @@ -1926,9 +1945,10 @@ dependencies = [ [[package]] name = "wasmer-interface-types" -version = "0.14.0" +version = "0.14.1" dependencies = [ "nom", + "wast", ] [[package]] @@ -1941,7 +1961,7 @@ dependencies = [ [[package]] name = "wasmer-llvm-backend" -version = "0.14.0" +version = "0.14.1" dependencies = [ "byteorder", "cc", @@ -1956,7 +1976,7 @@ dependencies = [ "smallvec 0.6.13", "wabt", "wasmer-runtime-core", - "wasmparser 0.45.2", + "wasmparser 0.51.3", "winapi", ] @@ -1972,14 +1992,14 @@ dependencies = [ [[package]] name = "wasmer-middleware-common" -version = "0.14.0" +version = "0.14.1" dependencies = [ "wasmer-runtime-core", ] [[package]] name = "wasmer-middleware-common-tests" -version = "0.14.0" +version = "0.14.1" dependencies = [ "criterion", "wabt", @@ -1992,7 +2012,7 @@ dependencies = [ [[package]] name = "wasmer-runtime" -version = "0.14.0" +version = "0.14.1" dependencies = [ "criterion", "lazy_static", @@ -2009,7 +2029,7 @@ dependencies = [ [[package]] name = "wasmer-runtime-c-api" -version = "0.14.0" +version = "0.14.1" dependencies = [ "cbindgen", "libc", @@ -2021,7 +2041,7 @@ dependencies = [ [[package]] name = "wasmer-runtime-core" -version = "0.14.0" +version = "0.14.1" dependencies = [ "bincode", "blake3", @@ -2041,15 +2061,15 @@ dependencies = [ "serde_bytes", "serde_derive", "smallvec 0.6.13", - "target-lexicon", + "target-lexicon 0.9.0", "wasm-debug", - "wasmparser 0.45.2", + "wasmparser 0.51.3", "winapi", ] [[package]] name = "wasmer-runtime-core-tests" -version = "0.14.0" +version = "0.14.1" dependencies = [ "wabt", "wasmer-clif-backend", @@ -2060,7 +2080,7 @@ dependencies = [ [[package]] name = "wasmer-singlepass-backend" -version = "0.14.0" +version = "0.14.1" dependencies = [ "bincode", "byteorder", @@ -2077,7 +2097,7 @@ dependencies = [ [[package]] name = "wasmer-spectests" -version = "0.14.0" +version = "0.14.1" dependencies = [ "glob 0.3.0", "wabt", @@ -2089,7 +2109,7 @@ dependencies = [ [[package]] name = "wasmer-wasi" -version = "0.14.0" +version = "0.14.1" dependencies = [ "bincode", "byteorder", @@ -2106,7 +2126,7 @@ dependencies = [ [[package]] name = "wasmer-wasi-experimental-io-devices" -version = "0.14.0" +version = "0.14.1" dependencies = [ "log", "minifb", @@ -2119,7 +2139,7 @@ dependencies = [ [[package]] name = "wasmer-wasi-tests" -version = "0.14.0" +version = "0.14.1" dependencies = [ "glob 0.3.0", "wasmer-clif-backend", @@ -2132,7 +2152,7 @@ dependencies = [ [[package]] name = "wasmer-win-exception-handler" -version = "0.14.0" +version = "0.14.1" dependencies = [ "cmake", "libc", @@ -2148,9 +2168,18 @@ checksum = "c702914acda5feeeffbc29e4d953e5b9ce79d8b98da4dbf18a77086e116c5470" [[package]] name = "wasmparser" -version = "0.45.2" +version = "0.51.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b4eab1d9971d0803729cba3617b56eb04fcb4bd25361cb63880ed41a42f20d5" +checksum = "447465bb5cf5ecd5918919ef3a0002e0839c87fb2a9483d4816d9b2cc36221fa" + +[[package]] +name = "wast" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9df3d716118a503b2f6bbb6ff46b21997ab0cc167b01de7a188e45e4b01e8d" +dependencies = [ + "leb128", +] [[package]] name = "winapi" diff --git a/Cargo.toml b/Cargo.toml index e5f11e4dc..1bf73378b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer" -version = "0.14.0" +version = "0.14.1" authors = ["The Wasmer Engineering Team "] edition = "2018" repository = "https://github.com/wasmerio/wasmer" diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 25c9cb166..805f3b3cb 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -24,7 +24,7 @@ jobs: - job: clippy_lint pool: - vmImage: "ubuntu-18.04" + vmImage: "ubuntu-16.04" steps: - checkout: self - template: .azure/install-rust.yml @@ -44,7 +44,7 @@ jobs: strategy: matrix: linux: - imageName: "ubuntu-18.04" + imageName: "ubuntu-16.04" rust_toolchain: nightly-2019-12-19 mac: imageName: "macos-10.14" @@ -88,7 +88,7 @@ jobs: - job: Check pool: - vmImage: "ubuntu-18.04" + vmImage: "ubuntu-16.04" variables: rust_toolchain: nightly-2019-12-19 condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying') @@ -106,7 +106,7 @@ jobs: strategy: matrix: linux: - imageName: "ubuntu-18.04" + imageName: "ubuntu-16.04" rust_toolchain: nightly-2019-12-19 mac: imageName: "macos-10.14" @@ -178,7 +178,7 @@ jobs: strategy: matrix: linux: - imageName: "ubuntu-18.04" + imageName: "ubuntu-16.04" rust_toolchain: nightly-2019-12-19 mac: imageName: "macos-10.14" @@ -234,7 +234,7 @@ jobs: - job: Build_Docs pool: - vmImage: "ubuntu-18.04" + vmImage: "ubuntu-16.04" variables: rust_toolchain: nightly-2019-12-19 condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying') @@ -309,7 +309,7 @@ jobs: - Build_Docs displayName: Deploy API Documentation to GitHub pool: - vmImage: "ubuntu-18.04" + vmImage: "ubuntu-16.04" condition: in(variables['Build.SourceBranch'], 'refs/heads/master') steps: - checkout: self diff --git a/lib/clif-backend/Cargo.toml b/lib/clif-backend/Cargo.toml index 185a63756..03cc445af 100644 --- a/lib/clif-backend/Cargo.toml +++ b/lib/clif-backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-clif-backend" -version = "0.14.0" +version = "0.14.1" description = "Wasmer runtime Cranelift compiler backend" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -11,14 +11,14 @@ edition = "2018" readme = "README.md" [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" } -cranelift-native = "0.52.0" -cranelift-codegen = "0.52.0" -cranelift-entity = "0.52.0" -cranelift-frontend = { package = "wasmer-clif-fork-frontend", version = "0.52.0" } -cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.52.0" } -target-lexicon = "0.9" -wasmparser = "0.45.0" +wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" } +cranelift-native = "0.59.0" +cranelift-codegen = "0.59.0" +cranelift-entity = "0.59.0" +cranelift-frontend = { package = "wasmer-clif-fork-frontend", version = "0.59.0" } +cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.59.0" } +target-lexicon = "0.10" +wasmparser = "0.51.3" byteorder = "1.3.2" nix = "0.15.0" libc = "0.2.60" @@ -38,7 +38,7 @@ version = "0.0.7" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] } -wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.14.0" } +wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.14.1" } [features] generate-debug-information = ["wasm-debug"] diff --git a/lib/clif-backend/README.md b/lib/clif-backend/README.md index 9c82c761d..63ffd24ca 100644 --- a/lib/clif-backend/README.md +++ b/lib/clif-backend/README.md @@ -1,6 +1,6 @@

- Wasmer logo + Wasmer logo

diff --git a/lib/clif-backend/src/code.rs b/lib/clif-backend/src/code.rs index b0e522740..67506f931 100644 --- a/lib/clif-backend/src/code.rs +++ b/lib/clif-backend/src/code.rs @@ -7,13 +7,14 @@ use crate::{ }; use cranelift_codegen::entity::EntityRef; -use cranelift_codegen::ir::{self, Ebb, Function, InstBuilder}; +use cranelift_codegen::ir::{self, Block, Function, InstBuilder}; use cranelift_codegen::isa::CallConv; use cranelift_codegen::{cursor::FuncCursor, isa}; use cranelift_frontend::{FunctionBuilder, Position, Variable}; use cranelift_wasm::{self, FuncTranslator, ModuleTranslationState}; use cranelift_wasm::{get_vmctx_value_label, translate_operator}; use cranelift_wasm::{FuncEnvironment, ReturnMode, TargetEnvironment, WasmError}; + use std::mem; use std::sync::{Arc, RwLock}; use wasmer_runtime_core::error::CompileError; @@ -110,7 +111,7 @@ impl ModuleCodeGenerator func_env.func.collect_debug_info(); } - debug_assert_eq!(func_env.func.dfg.num_ebbs(), 0, "Function must be empty"); + debug_assert_eq!(func_env.func.dfg.num_blocks(), 0, "Function must be empty"); debug_assert_eq!(func_env.func.dfg.num_insts(), 0, "Function must be empty"); let mut builder = FunctionBuilder::new( @@ -121,20 +122,20 @@ impl ModuleCodeGenerator builder.set_srcloc(ir::SourceLoc::new(loc.start())); - let entry_block = builder.create_ebb(); - builder.append_ebb_params_for_function_params(entry_block); + let entry_block = builder.create_block(); + builder.append_block_params_for_function_params(entry_block); builder.switch_to_block(entry_block); // This also creates values for the arguments. builder.seal_block(entry_block); // Make sure the entry block is inserted in the layout before we make any callbacks to // `environ`. The callback functions may need to insert things in the entry block. - builder.ensure_inserted_ebb(); + builder.ensure_inserted_block(); declare_wasm_parameters(&mut builder, entry_block); // Set up the translation state with a single pushed control block representing the whole // function and its return values. - let exit_block = builder.create_ebb(); - builder.append_ebb_params_for_function_returns(exit_block); + let exit_block = builder.create_block(); + builder.append_block_params_for_function_returns(exit_block); func_env .func_translator .state @@ -1021,7 +1022,7 @@ impl FuncEnvironment for FunctionEnvironment { _src: ir::Value, _len: ir::Value, ) -> cranelift_wasm::WasmResult<()> { - unimplemented!("table.copy yet implemented"); + unimplemented!("table.copy not yet implemented"); } fn translate_table_init( @@ -1034,7 +1035,7 @@ impl FuncEnvironment for FunctionEnvironment { _src: ir::Value, _len: ir::Value, ) -> cranelift_wasm::WasmResult<()> { - unimplemented!("table.init yet implemented"); + unimplemented!("table.init not yet implemented"); } fn translate_elem_drop( @@ -1042,7 +1043,72 @@ impl FuncEnvironment for FunctionEnvironment { _pos: FuncCursor, _seg_index: u32, ) -> cranelift_wasm::WasmResult<()> { - unimplemented!("elem.drop yet implemented"); + unimplemented!("elem.drop not yet implemented"); + } + + fn translate_table_grow( + &mut self, + _pos: FuncCursor, + _table_index: u32, + _delta: ir::Value, + _init_value: ir::Value, + ) -> cranelift_wasm::WasmResult { + unimplemented!("table.grow not yet implemented"); + } + + fn translate_table_get( + &mut self, + _pos: FuncCursor, + _table_index: u32, + _index: ir::Value, + ) -> cranelift_wasm::WasmResult { + unimplemented!("table.get not yet implemented"); + } + + fn translate_table_set( + &mut self, + _pos: FuncCursor, + _table_index: u32, + _value: ir::Value, + _index: ir::Value, + ) -> cranelift_wasm::WasmResult<()> { + unimplemented!("table.set not yet implemented"); + } + + fn translate_table_fill( + &mut self, + _pos: FuncCursor, + _table_index: u32, + _dst: ir::Value, + _val: ir::Value, + _len: ir::Value, + ) -> cranelift_wasm::WasmResult<()> { + unimplemented!("table.fill not yet implemented"); + } + + fn translate_ref_func( + &mut self, + _pos: FuncCursor, + _func_index: u32, + ) -> cranelift_wasm::WasmResult { + unimplemented!("ref.func not yet implemented"); + } + + fn translate_custom_global_get( + &mut self, + _pos: FuncCursor, + _global_index: cranelift_wasm::GlobalIndex, + ) -> cranelift_wasm::WasmResult { + unimplemented!("custom global.get not yet implemented"); + } + + fn translate_custom_global_set( + &mut self, + _pos: FuncCursor, + _global_index: cranelift_wasm::GlobalIndex, + _val: ir::Value, + ) -> cranelift_wasm::WasmResult<()> { + unimplemented!("custom global.set not yet implemented"); } } @@ -1242,7 +1308,7 @@ fn pointer_type(mcg: &CraneliftModuleCodeGenerator) -> ir::Type { /// Declare local variables for the signature parameters that correspond to WebAssembly locals. /// /// Return the number of local variables declared. -fn declare_wasm_parameters(builder: &mut FunctionBuilder, entry_block: Ebb) -> usize { +fn declare_wasm_parameters(builder: &mut FunctionBuilder, entry_block: Block) -> usize { let sig_len = builder.func.signature.params.len(); let mut next_local = 0; for i in 0..sig_len { @@ -1255,11 +1321,11 @@ fn declare_wasm_parameters(builder: &mut FunctionBuilder, entry_block: Ebb) -> u builder.declare_var(local, param_type.value_type); next_local += 1; - let param_value = builder.ebb_params(entry_block)[i]; + let param_value = builder.block_params(entry_block)[i]; builder.def_var(local, param_value); } if param_type.purpose == ir::ArgumentPurpose::VMContext { - let param_value = builder.ebb_params(entry_block)[i]; + let param_value = builder.block_params(entry_block)[i]; builder.set_val_label(param_value, get_vmctx_value_label()); } } diff --git a/lib/clif-backend/src/lib.rs b/lib/clif-backend/src/lib.rs index a989b2e43..95fd334a4 100644 --- a/lib/clif-backend/src/lib.rs +++ b/lib/clif-backend/src/lib.rs @@ -40,7 +40,7 @@ fn get_isa() -> Box { let flags = { let mut builder = settings::builder(); builder.set("opt_level", "speed_and_size").unwrap(); - builder.set("jump_tables_enabled", "false").unwrap(); + builder.set("enable_jump_tables", "false").unwrap(); if cfg!(test) || cfg!(debug_assertions) { builder.set("enable_verifier", "true").unwrap(); diff --git a/lib/clif-backend/src/relocation.rs b/lib/clif-backend/src/relocation.rs index a86bdeec9..cf01eb66c 100644 --- a/lib/clif-backend/src/relocation.rs +++ b/lib/clif-backend/src/relocation.rs @@ -98,7 +98,7 @@ pub struct RelocSink { } impl binemit::RelocSink for RelocSink { - fn reloc_ebb( + fn reloc_block( &mut self, _offset: binemit::CodeOffset, _reloc: binemit::Reloc, diff --git a/lib/clif-backend/src/resolver.rs b/lib/clif-backend/src/resolver.rs index 2e97ee699..37b94c030 100644 --- a/lib/clif-backend/src/resolver.rs +++ b/lib/clif-backend/src/resolver.rs @@ -159,12 +159,12 @@ impl FuncResolverBuilder { let debug_entry = if generate_debug_info { let func = &ctx.func; let encinfo = isa.encoding_info(); - let mut ebbs = func.layout.ebbs().collect::>(); - ebbs.sort_by_key(|ebb| func.offsets[*ebb]); - let instructions = ebbs + let mut blocks = func.layout.blocks().collect::>(); + blocks.sort_by_key(|block| func.offsets[*block]); + let instructions = blocks .into_iter() - .flat_map(|ebb| { - func.inst_offsets(ebb, &encinfo) + .flat_map(|block| { + func.inst_offsets(block, &encinfo) .map(|(offset, inst, length)| { let srcloc = func.srclocs[inst]; let val = srcloc.bits(); diff --git a/lib/clif-backend/src/trampoline.rs b/lib/clif-backend/src/trampoline.rs index fcd1ff83d..70854c1ea 100644 --- a/lib/clif-backend/src/trampoline.rs +++ b/lib/clif-backend/src/trampoline.rs @@ -16,7 +16,7 @@ use wasmer_runtime_core::{ struct NullRelocSink {} impl RelocSink for NullRelocSink { - fn reloc_ebb(&mut self, _: u32, _: Reloc, _: u32) {} + fn reloc_block(&mut self, _: u32, _: Reloc, _: u32) {} fn reloc_external(&mut self, _: u32, _: Reloc, _: &ir::ExternalName, _: i64) {} fn reloc_constant(&mut self, _: u32, _: Reloc, _: u32) { @@ -158,12 +158,12 @@ fn generate_func(func_sig: &FuncSig) -> ir::Function { let export_sig_ref = func.import_signature(generate_export_signature(func_sig)); - let entry_ebb = func.dfg.make_ebb(); - let vmctx_ptr = func.dfg.append_ebb_param(entry_ebb, ir::types::I64); - let func_ptr = func.dfg.append_ebb_param(entry_ebb, ir::types::I64); - let args_ptr = func.dfg.append_ebb_param(entry_ebb, ir::types::I64); - let returns_ptr = func.dfg.append_ebb_param(entry_ebb, ir::types::I64); - func.layout.append_ebb(entry_ebb); + let entry_ebb = func.dfg.make_block(); + let vmctx_ptr = func.dfg.append_block_param(entry_ebb, ir::types::I64); + let func_ptr = func.dfg.append_block_param(entry_ebb, ir::types::I64); + let args_ptr = func.dfg.append_block_param(entry_ebb, ir::types::I64); + let returns_ptr = func.dfg.append_block_param(entry_ebb, ir::types::I64); + func.layout.append_block(entry_ebb); let mut pos = FuncCursor::new(&mut func).at_first_insertion_point(entry_ebb); diff --git a/lib/dev-utils/Cargo.toml b/lib/dev-utils/Cargo.toml index aa39fda03..1d418a4cc 100644 --- a/lib/dev-utils/Cargo.toml +++ b/lib/dev-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-dev-utils" -version = "0.14.0" +version = "0.14.1" description = "Wasmer runtime core library" license = "MIT" authors = ["The Wasmer Engineering Team "] diff --git a/lib/dev-utils/README.md b/lib/dev-utils/README.md index 489d598fc..d198eaa70 100644 --- a/lib/dev-utils/README.md +++ b/lib/dev-utils/README.md @@ -1,3 +1,3 @@ # Dev Utils -This is shared code between the modules for testing and development only. Code in this crate will not be shipped. \ No newline at end of file +This is shared code between the modules for testing and development only. Code in this crate will not be shipped. diff --git a/lib/emscripten-tests/Cargo.toml b/lib/emscripten-tests/Cargo.toml index 217c2ae23..0b4710130 100644 --- a/lib/emscripten-tests/Cargo.toml +++ b/lib/emscripten-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-emscripten-tests" -version = "0.14.0" +version = "0.14.1" description = "Tests for our Emscripten implementation" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -9,15 +9,15 @@ publish = false build = "build/mod.rs" [dependencies] -wasmer-emscripten = { path = "../emscripten", version = "0.14.0" } -wasmer-runtime = { path = "../runtime", version = "0.14.0", default-features = false } -wasmer-clif-backend = { path = "../clif-backend", version = "0.14.0", optional = true} -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.0", optional = true, features = ["test"] } -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.0", optional = true } +wasmer-emscripten = { path = "../emscripten", version = "0.14.1" } +wasmer-runtime = { path = "../runtime", version = "0.14.1", default-features = false } +wasmer-clif-backend = { path = "../clif-backend", version = "0.14.1", optional = true} +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.1", optional = true, features = ["test"] } +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.1", optional = true } [dev-dependencies] wabt = "0.9.1" -wasmer-dev-utils = { path = "../dev-utils", version = "0.14.0"} +wasmer-dev-utils = { path = "../dev-utils", version = "0.14.1"} [build-dependencies] glob = "0.3" diff --git a/lib/emscripten/Cargo.toml b/lib/emscripten/Cargo.toml index 80e578bfd..3a4b790ed 100644 --- a/lib/emscripten/Cargo.toml +++ b/lib/emscripten/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-emscripten" -version = "0.14.0" +version = "0.14.1" description = "Wasmer runtime emscripten implementation library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -15,7 +15,7 @@ lazy_static = "1.4" libc = "0.2.60" log = "0.4" time = "0.1" -wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" } [target.'cfg(windows)'.dependencies] getrandom = "0.1" diff --git a/lib/interface-types/Cargo.toml b/lib/interface-types/Cargo.toml index 4dc01538c..e7b46a12d 100644 --- a/lib/interface-types/Cargo.toml +++ b/lib/interface-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-interface-types" -version = "0.14.0" +version = "0.14.1" description = "WebAssembly Interface Types library for Wasmer" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -9,3 +9,4 @@ edition = "2018" [dependencies] nom = "5.1" +wast = "8.0" diff --git a/lib/interface-types/README.md b/lib/interface-types/README.md index 8dcf3ffc8..242b14ea2 100644 --- a/lib/interface-types/README.md +++ b/lib/interface-types/README.md @@ -1,6 +1,6 @@

- Wasmer logo + Wasmer logo

diff --git a/lib/interface-types/src/ast.rs b/lib/interface-types/src/ast.rs index d8b82f588..d0c8cab8e 100644 --- a/lib/interface-types/src/ast.rs +++ b/lib/interface-types/src/ast.rs @@ -5,7 +5,7 @@ use crate::interpreter::Instruction; use std::str; /// Represents the types supported by WIT. -#[derive(PartialEq, Clone, Debug)] +#[derive(PartialEq, Debug)] pub enum InterfaceType { /// An integer. Int, @@ -190,7 +190,7 @@ pub struct Forward<'input> { /// Represents a set of interfaces, i.e. it entirely describes a WIT /// definition. -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Default, Debug)] pub struct Interfaces<'input> { /// All the exported functions. pub exports: Vec>, diff --git a/lib/interface-types/src/decoders/binary.rs b/lib/interface-types/src/decoders/binary.rs index e77238e7f..6beafc681 100644 --- a/lib/interface-types/src/decoders/binary.rs +++ b/lib/interface-types/src/decoders/binary.rs @@ -1,4 +1,4 @@ -//! Parse the WIT binary representation into an AST. +//! Parse the WIT binary representation into an [AST](crate::ast). use crate::{ast::*, interpreter::Instruction}; use nom::{ @@ -432,7 +432,8 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>( } /// Parse a sequence of bytes, expecting it to be a valid WIT binary -/// representation, into an `ast::Interfaces`. +/// representation, into an [`Interfaces`](crate::ast::Interfaces) +/// structure. /// /// # Example /// diff --git a/lib/interface-types/src/decoders/mod.rs b/lib/interface-types/src/decoders/mod.rs index 0ac9d881d..399bb896e 100644 --- a/lib/interface-types/src/decoders/mod.rs +++ b/lib/interface-types/src/decoders/mod.rs @@ -1,4 +1,6 @@ //! Reads the AST from a particular data representation; for instance, -//! `decoders::binary` reads the AST from a binary. +//! [`decoders::binary`](binary) reads the [AST](crate::ast) +//! from a binary. pub mod binary; +pub mod wat; diff --git a/lib/interface-types/src/decoders/wat.rs b/lib/interface-types/src/decoders/wat.rs new file mode 100644 index 000000000..7ef1d5472 --- /dev/null +++ b/lib/interface-types/src/decoders/wat.rs @@ -0,0 +1,881 @@ +//! Parse the WIT textual representation into an [AST](crate::ast). + +use crate::{ast::*, interpreter::Instruction}; +pub use wast::parser::ParseBuffer as Buffer; +use wast::{ + parser::{self, Cursor, Parse, Parser, Peek, Result}, + Id, LParen, +}; + +mod keyword { + pub use wast::{ + custom_keyword, + kw::{anyref, export, f32, f64, func, i32, i64, import, param, result}, + }; + + // New keywords. + custom_keyword!(adapt); + custom_keyword!(forward); + + // New types. + custom_keyword!(int); + custom_keyword!(float); + custom_keyword!(any); + custom_keyword!(string); + custom_keyword!(seq); + + // Instructions. + custom_keyword!(argument_get = "arg.get"); + custom_keyword!(call); + custom_keyword!(call_export = "call-export"); + custom_keyword!(read_utf8 = "read-utf8"); + custom_keyword!(write_utf8 = "write-utf8"); + custom_keyword!(as_wasm = "as-wasm"); + custom_keyword!(as_interface = "as-interface"); + custom_keyword!(table_ref_add = "table-ref-add"); + custom_keyword!(table_ref_get = "table-ref-get"); + custom_keyword!(call_method = "call-method"); + custom_keyword!(make_record = "make-record"); + custom_keyword!(get_field = "get-field"); + custom_keyword!(r#const = "const"); + custom_keyword!(fold_seq = "fold-seq"); + custom_keyword!(add); + custom_keyword!(mem_to_seq = "mem-to-seq"); + custom_keyword!(load); + custom_keyword!(seq_new = "seq.new"); + custom_keyword!(list_push = "list.push"); + custom_keyword!(repeat_until = "repeat-until"); +} + +/// Issue: Uppercased keyword aren't supported for the moment. +impl Parse<'_> for InterfaceType { + fn parse(parser: Parser<'_>) -> Result { + let mut lookahead = parser.lookahead1(); + + if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::Int) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::Float) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::Any) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::String) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::Seq) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::I32) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::I64) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::F32) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::F64) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::AnyRef) + } else { + Err(lookahead.error()) + } + } +} + +impl<'a> Parse<'a> for Instruction<'a> { + fn parse(parser: Parser<'a>) -> Result { + let mut lookahead = parser.lookahead1(); + + if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::ArgumentGet { + index: parser.parse()?, + }) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::Call { + function_index: parser.parse::()? as usize, + }) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::CallExport { + export_name: parser.parse()?, + }) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::ReadUtf8) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::WriteUtf8 { + allocator_name: parser.parse()?, + }) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::AsWasm(parser.parse()?)) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::AsInterface(parser.parse()?)) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::TableRefAdd) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::TableRefGet) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::CallMethod(parser.parse()?)) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::MakeRecord(parser.parse()?)) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::GetField(parser.parse()?, parser.parse()?)) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::Const(parser.parse()?, parser.parse()?)) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::FoldSeq(parser.parse()?)) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::Add(parser.parse()?)) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::MemToSeq(parser.parse()?, parser.parse()?)) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::Load(parser.parse()?, parser.parse()?)) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::SeqNew(parser.parse()?)) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::ListPush) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::RepeatUntil(parser.parse()?, parser.parse()?)) + } else { + Err(lookahead.error()) + } + } +} + +struct AtInterface; + +impl Peek for AtInterface { + fn peek(cursor: Cursor<'_>) -> bool { + cursor.reserved().map(|(string, _)| string) == Some("@interface") + } + + fn display() -> &'static str { + "`@interface`" + } +} + +impl Parse<'_> for AtInterface { + fn parse(parser: Parser<'_>) -> Result { + parser.step(|cursor| { + if let Some(("@interface", rest)) = cursor.reserved() { + return Ok((AtInterface, rest)); + } + + Err(cursor.error("expected `@interface`")) + }) + } +} + +#[derive(PartialEq, Debug)] +enum FunctionType { + Input(Vec), + Output(Vec), +} + +impl Parse<'_> for FunctionType { + fn parse(parser: Parser<'_>) -> Result { + parser.parens(|parser| { + let mut lookahead = parser.lookahead1(); + + if lookahead.peek::() { + parser.parse::()?; + + let mut inputs = vec![]; + + while !parser.is_empty() { + inputs.push(parser.parse()?); + } + + Ok(FunctionType::Input(inputs)) + } else if lookahead.peek::() { + parser.parse::()?; + + let mut outputs = vec![]; + + while !parser.is_empty() { + outputs.push(parser.parse()?); + } + + Ok(FunctionType::Output(outputs)) + } else { + Err(lookahead.error()) + } + }) + } +} + +#[derive(PartialEq, Debug)] +enum Interface<'a> { + Export(Export<'a>), + #[allow(dead_code)] + Type(Type<'a>), + Import(Import<'a>), + Adapter(Adapter<'a>), + Forward(Forward<'a>), +} + +impl<'a> Parse<'a> for Interface<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parens(|parser| { + let mut lookahead = parser.lookahead1(); + + if lookahead.peek::() { + parser.parse::()?; + + let mut lookahead = parser.lookahead1(); + + if lookahead.peek::() { + Ok(Interface::Export(parser.parse()?)) + } else if lookahead.peek::() { + Ok(Interface::Import(parser.parse()?)) + } else if lookahead.peek::() { + Ok(Interface::Adapter(parser.parse()?)) + } else if lookahead.peek::() { + Ok(Interface::Forward(parser.parse()?)) + } else { + Err(lookahead.error()) + } + } else { + Err(lookahead.error()) + } + }) + } +} + +impl<'a> Parse<'a> for Export<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + let name = parser.parse()?; + + let mut input_types = vec![]; + let mut output_types = vec![]; + + while !parser.is_empty() { + let function_type = parser.parse::()?; + + match function_type { + FunctionType::Input(mut inputs) => input_types.append(&mut inputs), + FunctionType::Output(mut outputs) => output_types.append(&mut outputs), + } + } + + Ok(Export { + name, + input_types, + output_types, + }) + } +} + +impl<'a> Parse<'a> for Import<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + parser.parse::()?; + + let (namespace, name) = parser.parens(|parser| { + parser.parse::()?; + + Ok((parser.parse()?, parser.parse()?)) + })?; + let mut input_types = vec![]; + let mut output_types = vec![]; + + while !parser.is_empty() { + let function_type = parser.parse::()?; + + match function_type { + FunctionType::Input(mut inputs) => input_types.append(&mut inputs), + FunctionType::Output(mut outputs) => output_types.append(&mut outputs), + } + } + + Ok(Import { + namespace, + name, + input_types, + output_types, + }) + } +} + +impl<'a> Parse<'a> for Adapter<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + + let (kind, namespace, name) = parser.parens(|parser| { + let mut lookahead = parser.lookahead1(); + + if lookahead.peek::() { + parser.parse::()?; + + Ok((AdapterKind::Import, parser.parse()?, parser.parse()?)) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok((AdapterKind::Export, "", parser.parse()?)) + } else { + Err(lookahead.error()) + } + })?; + let mut input_types = vec![]; + let mut output_types = vec![]; + let mut instructions = vec![]; + + while !parser.is_empty() { + if parser.peek::() { + let function_type = parser.parse::()?; + + match function_type { + FunctionType::Input(mut inputs) => input_types.append(&mut inputs), + FunctionType::Output(mut outputs) => output_types.append(&mut outputs), + } + } else { + instructions.push(parser.parse()?); + } + } + + Ok(match kind { + AdapterKind::Import => Adapter::Import { + namespace, + name, + input_types, + output_types, + instructions, + }, + + AdapterKind::Export => Adapter::Export { + name, + input_types, + output_types, + instructions, + }, + + _ => unimplemented!("Adapter of kind “helper” is not implemented yet."), + }) + } +} + +impl<'a> Parse<'a> for Forward<'a> { + fn parse(parser: Parser<'a>) -> Result { + parser.parse::()?; + + let name = parser.parens(|parser| { + parser.parse::()?; + + Ok(parser.parse()?) + })?; + + Ok(Forward { name }) + } +} + +impl<'a> Parse<'a> for Interfaces<'a> { + fn parse(parser: Parser<'a>) -> Result { + let mut interfaces: Interfaces = Default::default(); + + while !parser.is_empty() { + let interface = parser.parse::()?; + + match interface { + Interface::Export(export) => interfaces.exports.push(export), + Interface::Type(ty) => interfaces.types.push(ty), + Interface::Import(import) => interfaces.imports.push(import), + Interface::Adapter(adapter) => interfaces.adapters.push(adapter), + Interface::Forward(forward) => interfaces.forwards.push(forward), + } + } + + Ok(interfaces) + } +} + +/// Parse a WIT definition in its textual format, and produces an +/// [AST](crate::ast) with the [`Interfaces`](crate::ast::Interfaces) +/// structure upon succesful. +/// +/// # Examples +/// +/// ```rust +/// use wasmer_interface_types::{ +/// ast::*, +/// decoders::wat::{parse, Buffer}, +/// interpreter::Instruction, +/// }; +/// +/// # fn main() { +/// let input = Buffer::new( +/// r#"(@interface export "foo" +/// (param i32)) +/// +/// (@interface export "bar") +/// +/// (@interface func $ns_foo (import "ns" "foo") +/// (result i32)) +/// +/// (@interface func $ns_bar (import "ns" "bar")) +/// +/// (@interface adapt (import "ns" "foo") +/// (param i32) +/// arg.get 42) +/// +/// (@interface adapt (export "bar") +/// arg.get 42) +/// +/// (@interface forward (export "main"))"#, +/// ) +/// .unwrap(); +/// let output = Interfaces { +/// exports: vec![ +/// Export { +/// name: "foo", +/// input_types: vec![InterfaceType::I32], +/// output_types: vec![], +/// }, +/// Export { +/// name: "bar", +/// input_types: vec![], +/// output_types: vec![], +/// }, +/// ], +/// types: vec![], +/// imports: vec![ +/// Import { +/// namespace: "ns", +/// name: "foo", +/// input_types: vec![], +/// output_types: vec![InterfaceType::I32], +/// }, +/// Import { +/// namespace: "ns", +/// name: "bar", +/// input_types: vec![], +/// output_types: vec![], +/// }, +/// ], +/// adapters: vec![ +/// Adapter::Import { +/// namespace: "ns", +/// name: "foo", +/// input_types: vec![InterfaceType::I32], +/// output_types: vec![], +/// instructions: vec![Instruction::ArgumentGet { index: 42 }], +/// }, +/// Adapter::Export { +/// name: "bar", +/// input_types: vec![], +/// output_types: vec![], +/// instructions: vec![Instruction::ArgumentGet { index: 42 }], +/// }, +/// ], +/// forwards: vec![Forward { name: "main" }], +/// }; +/// +/// assert_eq!(parse(&input).unwrap(), output); +/// # } +/// ``` +pub fn parse<'input>(input: &'input Buffer) -> Result> { + parser::parse::(&input) +} + +#[cfg(test)] +mod tests { + use super::*; + use wast::parser; + + fn buffer(input: &str) -> Buffer { + Buffer::new(input).expect("Failed to build the parser buffer.") + } + + #[test] + fn test_interface_type() { + let inputs = vec![ + "int", "float", "any", "string", "seq", "i32", "i64", "f32", "f64", "anyref", + ]; + let outputs = vec![ + InterfaceType::Int, + InterfaceType::Float, + InterfaceType::Any, + InterfaceType::String, + InterfaceType::Seq, + InterfaceType::I32, + InterfaceType::I64, + InterfaceType::F32, + InterfaceType::F64, + InterfaceType::AnyRef, + ]; + + assert_eq!(inputs.len(), outputs.len()); + + for (input, output) in inputs.iter().zip(outputs.iter()) { + assert_eq!( + &parser::parse::(&buffer(input)).unwrap(), + output + ); + } + } + + #[test] + fn test_instructions() { + let inputs = vec![ + "arg.get 7", + "call 7", + r#"call-export "foo""#, + "read-utf8", + r#"write-utf8 "foo""#, + "as-wasm int", + "as-interface anyref", + "table-ref-add", + "table-ref-get", + "call-method 7", + "make-record int", + "get-field int 7", + "const i32 7", + "fold-seq 7", + "add int", + r#"mem-to-seq int "foo""#, + r#"load int "foo""#, + "seq.new int", + "list.push", + "repeat-until 1 2", + ]; + let outputs = vec![ + Instruction::ArgumentGet { index: 7 }, + Instruction::Call { function_index: 7 }, + Instruction::CallExport { export_name: "foo" }, + Instruction::ReadUtf8, + Instruction::WriteUtf8 { + allocator_name: "foo", + }, + Instruction::AsWasm(InterfaceType::Int), + Instruction::AsInterface(InterfaceType::AnyRef), + Instruction::TableRefAdd, + Instruction::TableRefGet, + Instruction::CallMethod(7), + Instruction::MakeRecord(InterfaceType::Int), + Instruction::GetField(InterfaceType::Int, 7), + Instruction::Const(InterfaceType::I32, 7), + Instruction::FoldSeq(7), + Instruction::Add(InterfaceType::Int), + Instruction::MemToSeq(InterfaceType::Int, "foo"), + Instruction::Load(InterfaceType::Int, "foo"), + Instruction::SeqNew(InterfaceType::Int), + Instruction::ListPush, + Instruction::RepeatUntil(1, 2), + ]; + + assert_eq!(inputs.len(), outputs.len()); + + for (input, output) in inputs.iter().zip(outputs.iter()) { + assert_eq!( + &parser::parse::(&buffer(input)).unwrap(), + output + ); + } + } + + #[test] + fn test_param_empty() { + let input = buffer("(param)"); + let output = FunctionType::Input(vec![]); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_param() { + let input = buffer("(param i32 string)"); + let output = FunctionType::Input(vec![InterfaceType::I32, InterfaceType::String]); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_result_empty() { + let input = buffer("(result)"); + let output = FunctionType::Output(vec![]); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_result() { + let input = buffer("(result i32 string)"); + let output = FunctionType::Output(vec![InterfaceType::I32, InterfaceType::String]); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_export_with_no_param_no_result() { + let input = buffer(r#"(@interface export "foo")"#); + let output = Interface::Export(Export { + name: "foo", + input_types: vec![], + output_types: vec![], + }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_export_with_some_param_no_result() { + let input = buffer(r#"(@interface export "foo" (param i32))"#); + let output = Interface::Export(Export { + name: "foo", + input_types: vec![InterfaceType::I32], + output_types: vec![], + }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_export_with_no_param_some_result() { + let input = buffer(r#"(@interface export "foo" (result i32))"#); + let output = Interface::Export(Export { + name: "foo", + input_types: vec![], + output_types: vec![InterfaceType::I32], + }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_export_with_some_param_some_result() { + let input = buffer(r#"(@interface export "foo" (param string) (result i32 i32))"#); + let output = Interface::Export(Export { + name: "foo", + input_types: vec![InterfaceType::String], + output_types: vec![InterfaceType::I32, InterfaceType::I32], + }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_export_escaped_name() { + let input = buffer(r#"(@interface export "fo\"o")"#); + let output = Interface::Export(Export { + name: r#"fo"o"#, + input_types: vec![], + output_types: vec![], + }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_import_with_no_param_no_result() { + let input = buffer(r#"(@interface func $ns_foo (import "ns" "foo"))"#); + let output = Interface::Import(Import { + namespace: "ns", + name: "foo", + input_types: vec![], + output_types: vec![], + }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_import_with_some_param_no_result() { + let input = buffer(r#"(@interface func $ns_foo (import "ns" "foo") (param i32))"#); + let output = Interface::Import(Import { + namespace: "ns", + name: "foo", + input_types: vec![InterfaceType::I32], + output_types: vec![], + }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_import_with_no_param_some_result() { + let input = buffer(r#"(@interface func $ns_foo (import "ns" "foo") (result i32))"#); + let output = Interface::Import(Import { + namespace: "ns", + name: "foo", + input_types: vec![], + output_types: vec![InterfaceType::I32], + }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_import_with_some_param_some_result() { + let input = buffer( + r#"(@interface func $ns_foo (import "ns" "foo") (param string) (result i32 i32))"#, + ); + let output = Interface::Import(Import { + namespace: "ns", + name: "foo", + input_types: vec![InterfaceType::String], + output_types: vec![InterfaceType::I32, InterfaceType::I32], + }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_adapter_import() { + let input = + buffer(r#"(@interface adapt (import "ns" "foo") (param i32 i32) (result i32))"#); + let output = Interface::Adapter(Adapter::Import { + namespace: "ns", + name: "foo", + input_types: vec![InterfaceType::I32, InterfaceType::I32], + output_types: vec![InterfaceType::I32], + instructions: vec![], + }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_adapter_export() { + let input = buffer(r#"(@interface adapt (export "foo") (param i32 i32) (result i32))"#); + let output = Interface::Adapter(Adapter::Export { + name: "foo", + input_types: vec![InterfaceType::I32, InterfaceType::I32], + output_types: vec![InterfaceType::I32], + instructions: vec![], + }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + #[test] + fn test_forward() { + let input = buffer(r#"(@interface forward (export "foo"))"#); + let output = Interface::Forward(Forward { name: "foo" }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + + #[test] + fn test_interfaces() { + let input = buffer( + r#"(@interface export "foo" + (param i32)) + +(@interface export "bar") + +(@interface func $ns_foo (import "ns" "foo") + (result i32)) + +(@interface func $ns_bar (import "ns" "bar")) + +(@interface adapt (import "ns" "foo") + (param i32) + arg.get 42) + +(@interface adapt (export "bar") + arg.get 42) + +(@interface forward (export "main"))"#, + ); + let output = Interfaces { + exports: vec![ + Export { + name: "foo", + input_types: vec![InterfaceType::I32], + output_types: vec![], + }, + Export { + name: "bar", + input_types: vec![], + output_types: vec![], + }, + ], + types: vec![], + imports: vec![ + Import { + namespace: "ns", + name: "foo", + input_types: vec![], + output_types: vec![InterfaceType::I32], + }, + Import { + namespace: "ns", + name: "bar", + input_types: vec![], + output_types: vec![], + }, + ], + adapters: vec![ + Adapter::Import { + namespace: "ns", + name: "foo", + input_types: vec![InterfaceType::I32], + output_types: vec![], + instructions: vec![Instruction::ArgumentGet { index: 42 }], + }, + Adapter::Export { + name: "bar", + input_types: vec![], + output_types: vec![], + instructions: vec![Instruction::ArgumentGet { index: 42 }], + }, + ], + forwards: vec![Forward { name: "main" }], + }; + + assert_eq!(parser::parse::(&input).unwrap(), output); + } +} diff --git a/lib/interface-types/src/interpreter/mod.rs b/lib/interface-types/src/interpreter/mod.rs index 792c91e89..e7ef7f1b1 100644 --- a/lib/interface-types/src/interpreter/mod.rs +++ b/lib/interface-types/src/interpreter/mod.rs @@ -43,8 +43,8 @@ pub(crate) type ExecutableInstruction"] repository = "https://github.com/wasmerio/wasmer" @@ -10,8 +10,8 @@ edition = "2018" readme = "README.md" [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" } -wasmparser = "0.45.0" +wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" } +wasmparser = "0.51.3" smallvec = "0.6" goblin = "0.0.24" libc = "0.2.60" diff --git a/lib/llvm-backend/README.md b/lib/llvm-backend/README.md index 584b37585..78e66d1c9 100644 --- a/lib/llvm-backend/README.md +++ b/lib/llvm-backend/README.md @@ -1,6 +1,6 @@

- Wasmer logo + Wasmer logo

diff --git a/lib/llvm-backend/src/code.rs b/lib/llvm-backend/src/code.rs index 5d568e7cd..d33e67fac 100644 --- a/lib/llvm-backend/src/code.rs +++ b/lib/llvm-backend/src/code.rs @@ -37,7 +37,7 @@ use wasmer_runtime_core::{ codegen::*, memory::MemoryType, module::{ModuleInfo, ModuleInner}, - parse::wp_type_to_type, + parse::{wp_type_to_type, LoadError}, structures::{Map, TypedIndex}, types::{ FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, SigIndex, TableIndex, Type, @@ -670,7 +670,7 @@ fn resolve_memory_ptr<'ctx>( memarg: &MemoryImmediate, ptr_ty: PointerType<'ctx>, value_size: usize, -) -> Result, BinaryReaderError> { +) -> Result, CodegenError> { // Look up the memory base (as pointer) and bounds (as unsigned integer). let memory_cache = ctx.memory(MemoryIndex::new(0), intrinsics, module.clone()); let (mem_base, mem_bound, minimum, _maximum) = match memory_cache { @@ -958,7 +958,6 @@ pub struct LLVMModuleCodeGenerator<'ctx> { intrinsics: Option>, functions: Vec>, signatures: Map>, - signatures_raw: Map, function_signatures: Option>>, llvm_functions: Rc>>>, func_import_count: usize, @@ -1206,9 +1205,8 @@ impl<'ctx> FunctionCodeGenerator for LLVMFunctionCodeGenerator<'ct * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#control-flow-instructions ***************************/ Operator::Block { ty } => { - let current_block = builder.get_insert_block().ok_or(BinaryReaderError { - message: "not currently in a block", - offset: -1isize as usize, + let current_block = builder.get_insert_block().ok_or(CodegenError { + message: "not currently in a block".to_string(), })?; let end_block = context.append_basic_block(function, "end"); @@ -1282,9 +1280,8 @@ impl<'ctx> FunctionCodeGenerator for LLVMFunctionCodeGenerator<'ct Operator::Br { relative_depth } => { let frame = state.frame_at_depth(relative_depth)?; - let current_block = builder.get_insert_block().ok_or(BinaryReaderError { - message: "not currently in a block", - offset: -1isize as usize, + let current_block = builder.get_insert_block().ok_or(CodegenError { + message: "not currently in a block".to_string(), })?; let value_len = if frame.is_loop() { @@ -1314,9 +1311,8 @@ impl<'ctx> FunctionCodeGenerator for LLVMFunctionCodeGenerator<'ct let cond = state.pop1()?; let frame = state.frame_at_depth(relative_depth)?; - let current_block = builder.get_insert_block().ok_or(BinaryReaderError { - message: "not currently in a block", - offset: -1isize as usize, + let current_block = builder.get_insert_block().ok_or(CodegenError { + message: "not currently in a block".to_string(), })?; let value_len = if frame.is_loop() { @@ -1346,9 +1342,8 @@ impl<'ctx> FunctionCodeGenerator for LLVMFunctionCodeGenerator<'ct builder.position_at_end(&else_block); } Operator::BrTable { ref table } => { - let current_block = builder.get_insert_block().ok_or(BinaryReaderError { - message: "not currently in a block", - offset: -1isize as usize, + let current_block = builder.get_insert_block().ok_or(CodegenError { + message: "not currently in a block".to_string(), })?; let (label_depths, default_depth) = table.read_table()?; @@ -1372,7 +1367,7 @@ impl<'ctx> FunctionCodeGenerator for LLVMFunctionCodeGenerator<'ct .iter() .enumerate() .map(|(case_index, &depth)| { - let frame_result: Result<&ControlFrame, BinaryReaderError> = + let frame_result: Result<&ControlFrame, CodegenError> = state.frame_at_depth(depth); let frame = match frame_result { Ok(v) => v, @@ -1396,9 +1391,8 @@ impl<'ctx> FunctionCodeGenerator for LLVMFunctionCodeGenerator<'ct state.reachable = false; } Operator::If { ty } => { - let current_block = builder.get_insert_block().ok_or(BinaryReaderError { - message: "not currently in a block", - offset: -1isize as usize, + let current_block = builder.get_insert_block().ok_or(CodegenError { + message: "not currently in a block".to_string(), })?; let if_then_block = context.append_basic_block(function, "if_then"); let if_else_block = context.append_basic_block(function, "if_else"); @@ -1437,9 +1431,8 @@ impl<'ctx> FunctionCodeGenerator for LLVMFunctionCodeGenerator<'ct Operator::Else => { if state.reachable { let frame = state.frame_at_depth(0)?; - let current_block = builder.get_insert_block().ok_or(BinaryReaderError { - message: "not currently in a block", - offset: -1isize as usize, + let current_block = builder.get_insert_block().ok_or(CodegenError { + message: "not currently in a block".to_string(), })?; for phi in frame.phis().to_vec().iter().rev() { @@ -1471,9 +1464,8 @@ impl<'ctx> FunctionCodeGenerator for LLVMFunctionCodeGenerator<'ct Operator::End => { let frame = state.pop_frame()?; - let current_block = builder.get_insert_block().ok_or(BinaryReaderError { - message: "not currently in a block", - offset: -1isize as usize, + let current_block = builder.get_insert_block().ok_or(CodegenError { + message: "not currently in a block".to_string(), })?; if state.reachable { @@ -1530,9 +1522,8 @@ impl<'ctx> FunctionCodeGenerator for LLVMFunctionCodeGenerator<'ct } } Operator::Return => { - let current_block = builder.get_insert_block().ok_or(BinaryReaderError { - message: "not currently in a block", - offset: -1isize as usize, + let current_block = builder.get_insert_block().ok_or(CodegenError { + message: "not currently in a block".to_string(), })?; let frame = state.outermost_frame()?; @@ -8617,6 +8608,14 @@ impl From for CodegenError { } } +impl From for CodegenError { + fn from(other: LoadError) -> CodegenError { + CodegenError { + message: format!("{:?}", other), + } + } +} + impl Drop for LLVMModuleCodeGenerator<'_> { fn drop(&mut self) { // Ensure that all members of the context are dropped before we drop the context. @@ -8716,7 +8715,6 @@ impl<'ctx> ModuleCodeGenerator, LLVMBackend, Cod module: ManuallyDrop::new(Rc::new(RefCell::new(module))), functions: vec![], signatures: Map::new(), - signatures_raw: Map::new(), function_signatures: None, llvm_functions: Rc::new(RefCell::new(HashMap::new())), func_import_count: 0, @@ -8738,7 +8736,7 @@ impl<'ctx> ModuleCodeGenerator, LLVMBackend, Cod fn next_function( &mut self, - _module_info: Arc>, + module_info: Arc>, _loc: WasmSpan, ) -> Result<&mut LLVMFunctionCodeGenerator<'ctx>, CodegenError> { // Creates a new function and returns the function-scope code generator for it. @@ -8757,7 +8755,7 @@ impl<'ctx> ModuleCodeGenerator, LLVMBackend, Cod let func_index = FuncIndex::new(self.func_import_count + self.functions.len()); let sig_id = self.function_signatures.as_ref().unwrap()[func_index]; - let func_sig = self.signatures_raw[sig_id].clone(); + let func_sig = module_info.read().unwrap().signatures[sig_id].clone(); let function = &self.llvm_functions.borrow_mut()[&func_index]; function.set_personality_function(*self.personality_func); @@ -8965,7 +8963,6 @@ impl<'ctx> ModuleCodeGenerator, LLVMBackend, Cod ) }) .collect(); - self.signatures_raw = signatures.clone(); Ok(()) } diff --git a/lib/llvm-backend/src/read_info.rs b/lib/llvm-backend/src/read_info.rs index 6f7fbca5e..958d3a49e 100644 --- a/lib/llvm-backend/src/read_info.rs +++ b/lib/llvm-backend/src/read_info.rs @@ -1,15 +1,16 @@ +use crate::code::CodegenError; use wasmer_runtime_core::parse::wp_type_to_type; use wasmer_runtime_core::types::Type; -use wasmparser::{BinaryReaderError, TypeOrFuncType as WpTypeOrFuncType}; +use wasmparser::TypeOrFuncType as WpTypeOrFuncType; -pub fn blocktype_to_type(ty: WpTypeOrFuncType) -> Result { +pub fn blocktype_to_type(ty: WpTypeOrFuncType) -> Result { match ty { - WpTypeOrFuncType::Type(inner_ty) => wp_type_to_type(inner_ty), + WpTypeOrFuncType::Type(inner_ty) => Ok(wp_type_to_type(inner_ty)?), _ => { - return Err(BinaryReaderError { + return Err(CodegenError { message: - "the wasmer llvm backend does not yet support the multi-value return extension", - offset: -1isize as usize, + "the wasmer llvm backend does not yet support the multi-value return extension" + .to_string(), }); } } diff --git a/lib/llvm-backend/src/state.rs b/lib/llvm-backend/src/state.rs index 8db358fe2..ed3f8bb3a 100644 --- a/lib/llvm-backend/src/state.rs +++ b/lib/llvm-backend/src/state.rs @@ -1,3 +1,4 @@ +use crate::code::CodegenError; use inkwell::{ basic_block::BasicBlock, values::{BasicValue, BasicValueEnum, PhiValue}, @@ -5,7 +6,6 @@ use inkwell::{ use smallvec::SmallVec; use std::cell::Cell; use std::ops::{BitAnd, BitOr, BitOrAssign}; -use wasmparser::BinaryReaderError; #[derive(Debug)] pub enum ControlFrame<'ctx> { @@ -229,21 +229,19 @@ impl<'ctx> State<'ctx> { self.stack.truncate(stack_size_snapshot); } - pub fn outermost_frame(&self) -> Result<&ControlFrame<'ctx>, BinaryReaderError> { - self.control_stack.get(0).ok_or(BinaryReaderError { - message: "outermost_frame: invalid control stack depth", - offset: -1isize as usize, + pub fn outermost_frame(&self) -> Result<&ControlFrame<'ctx>, CodegenError> { + self.control_stack.get(0).ok_or(CodegenError { + message: "outermost_frame: invalid control stack depth".to_string(), }) } - pub fn frame_at_depth(&self, depth: u32) -> Result<&ControlFrame<'ctx>, BinaryReaderError> { + pub fn frame_at_depth(&self, depth: u32) -> Result<&ControlFrame<'ctx>, CodegenError> { let index = self .control_stack .len() .checked_sub(1 + (depth as usize)) - .ok_or(BinaryReaderError { - message: "frame_at_depth: invalid control stack depth", - offset: -1isize as usize, + .ok_or(CodegenError { + message: "frame_at_depth: invalid control stack depth".to_string(), })?; Ok(&self.control_stack[index]) } @@ -251,22 +249,20 @@ impl<'ctx> State<'ctx> { pub fn frame_at_depth_mut( &mut self, depth: u32, - ) -> Result<&mut ControlFrame<'ctx>, BinaryReaderError> { + ) -> Result<&mut ControlFrame<'ctx>, CodegenError> { let index = self .control_stack .len() .checked_sub(1 + (depth as usize)) - .ok_or(BinaryReaderError { - message: "frame_at_depth_mut: invalid control stack depth", - offset: -1isize as usize, + .ok_or(CodegenError { + message: "frame_at_depth_mut: invalid control stack depth".to_string(), })?; Ok(&mut self.control_stack[index]) } - pub fn pop_frame(&mut self) -> Result, BinaryReaderError> { - self.control_stack.pop().ok_or(BinaryReaderError { - message: "pop_frame: cannot pop from control stack", - offset: -1isize as usize, + pub fn pop_frame(&mut self) -> Result, CodegenError> { + self.control_stack.pop().ok_or(CodegenError { + message: "pop_frame: cannot pop from control stack".to_string(), }) } @@ -285,20 +281,17 @@ impl<'ctx> State<'ctx> { self.stack.push((value.as_basic_value_enum(), info)); } - pub fn pop1(&mut self) -> Result, BinaryReaderError> { + pub fn pop1(&mut self) -> Result, CodegenError> { Ok(self.pop1_extra()?.0) } - pub fn pop1_extra(&mut self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), BinaryReaderError> { - self.stack.pop().ok_or(BinaryReaderError { - message: "pop1_extra: invalid value stack", - offset: -1isize as usize, + pub fn pop1_extra(&mut self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), CodegenError> { + self.stack.pop().ok_or(CodegenError { + message: "pop1_extra: invalid value stack".to_string(), }) } - pub fn pop2( - &mut self, - ) -> Result<(BasicValueEnum<'ctx>, BasicValueEnum<'ctx>), BinaryReaderError> { + pub fn pop2(&mut self) -> Result<(BasicValueEnum<'ctx>, BasicValueEnum<'ctx>), CodegenError> { let v2 = self.pop1()?; let v1 = self.pop1()?; Ok((v1, v2)) @@ -311,7 +304,7 @@ impl<'ctx> State<'ctx> { (BasicValueEnum<'ctx>, ExtraInfo), (BasicValueEnum<'ctx>, ExtraInfo), ), - BinaryReaderError, + CodegenError, > { let v2 = self.pop1_extra()?; let v1 = self.pop1_extra()?; @@ -326,7 +319,7 @@ impl<'ctx> State<'ctx> { (BasicValueEnum<'ctx>, ExtraInfo), (BasicValueEnum<'ctx>, ExtraInfo), ), - BinaryReaderError, + CodegenError, > { let v3 = self.pop1_extra()?; let v2 = self.pop1_extra()?; @@ -334,25 +327,23 @@ impl<'ctx> State<'ctx> { Ok((v1, v2, v3)) } - pub fn peek1_extra(&self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), BinaryReaderError> { - let index = self.stack.len().checked_sub(1).ok_or(BinaryReaderError { - message: "peek1_extra: invalid value stack", - offset: -1isize as usize, + pub fn peek1_extra(&self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), CodegenError> { + let index = self.stack.len().checked_sub(1).ok_or(CodegenError { + message: "peek1_extra: invalid value stack".to_string(), })?; Ok(self.stack[index]) } - pub fn peekn(&self, n: usize) -> Result>, BinaryReaderError> { + pub fn peekn(&self, n: usize) -> Result>, CodegenError> { Ok(self.peekn_extra(n)?.iter().map(|x| x.0).collect()) } pub fn peekn_extra( &self, n: usize, - ) -> Result<&[(BasicValueEnum<'ctx>, ExtraInfo)], BinaryReaderError> { - let index = self.stack.len().checked_sub(n).ok_or(BinaryReaderError { - message: "peekn_extra: invalid value stack", - offset: -1isize as usize, + ) -> Result<&[(BasicValueEnum<'ctx>, ExtraInfo)], CodegenError> { + let index = self.stack.len().checked_sub(n).ok_or(CodegenError { + message: "peekn_extra: invalid value stack".to_string(), })?; Ok(&self.stack[index..]) @@ -361,16 +352,15 @@ impl<'ctx> State<'ctx> { pub fn popn_save_extra( &mut self, n: usize, - ) -> Result, ExtraInfo)>, BinaryReaderError> { + ) -> Result, ExtraInfo)>, CodegenError> { let v = self.peekn_extra(n)?.to_vec(); self.popn(n)?; Ok(v) } - pub fn popn(&mut self, n: usize) -> Result<(), BinaryReaderError> { - let index = self.stack.len().checked_sub(n).ok_or(BinaryReaderError { - message: "popn: invalid value stack", - offset: -1isize as usize, + pub fn popn(&mut self, n: usize) -> Result<(), CodegenError> { + let index = self.stack.len().checked_sub(n).ok_or(CodegenError { + message: "popn: invalid value stack".to_string(), })?; self.stack.truncate(index); diff --git a/lib/middleware-common-tests/Cargo.toml b/lib/middleware-common-tests/Cargo.toml index 329b71ccc..c66f51826 100644 --- a/lib/middleware-common-tests/Cargo.toml +++ b/lib/middleware-common-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-middleware-common-tests" -version = "0.14.0" +version = "0.14.1" authors = ["The Wasmer Engineering Team "] edition = "2018" repository = "https://github.com/wasmerio/wasmer" @@ -8,11 +8,11 @@ license = "MIT" publish = false [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" } -wasmer-middleware-common = { path = "../middleware-common", version = "0.14.0" } -wasmer-clif-backend = { path = "../clif-backend", version = "0.14.0", optional = true } -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.0", features = ["test"], optional = true } -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.0", optional = true } +wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" } +wasmer-middleware-common = { path = "../middleware-common", version = "0.14.1" } +wasmer-clif-backend = { path = "../clif-backend", version = "0.14.1", optional = true } +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.1", features = ["test"], optional = true } +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.1", optional = true } [features] clif = ["wasmer-clif-backend"] diff --git a/lib/middleware-common/Cargo.toml b/lib/middleware-common/Cargo.toml index a997bbc44..31707372f 100644 --- a/lib/middleware-common/Cargo.toml +++ b/lib/middleware-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-middleware-common" -version = "0.14.0" +version = "0.14.1" repository = "https://github.com/wasmerio/wasmer" description = "Wasmer runtime common middlewares" license = "MIT" @@ -10,4 +10,4 @@ categories = ["wasm"] edition = "2018" [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" } diff --git a/lib/runtime-c-api/Cargo.toml b/lib/runtime-c-api/Cargo.toml index 8744e7266..3ba6fd94b 100644 --- a/lib/runtime-c-api/Cargo.toml +++ b/lib/runtime-c-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-runtime-c-api" -version = "0.14.0" +version = "0.14.1" description = "Wasmer C API library" documentation = "https://wasmerio.github.io/wasmer/c/runtime-c-api/" license = "MIT" @@ -20,22 +20,22 @@ libc = "0.2.60" [dependencies.wasmer-runtime] default-features = false path = "../runtime" -version = "0.14.0" +version = "0.14.1" [dependencies.wasmer-runtime-core] default-features = false path = "../runtime-core" -version = "0.14.0" +version = "0.14.1" [dependencies.wasmer-wasi] default-features = false path = "../wasi" -version = "0.14.0" +version = "0.14.1" optional = true [dependencies.wasmer-emscripten] path = "../emscripten" -version = "0.14.0" +version = "0.14.1" optional = true [features] diff --git a/lib/runtime-c-api/README.md b/lib/runtime-c-api/README.md index d7d3b4ea3..d1475b7fd 100644 --- a/lib/runtime-c-api/README.md +++ b/lib/runtime-c-api/README.md @@ -1,6 +1,6 @@

- Wasmer logo + Wasmer logo

diff --git a/lib/runtime-c-api/doxyfile b/lib/runtime-c-api/doxyfile index bcb152118..e38b94b75 100644 --- a/lib/runtime-c-api/doxyfile +++ b/lib/runtime-c-api/doxyfile @@ -7,7 +7,7 @@ DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "wasmer-runtime-c-api" PROJECT_NUMBER = PROJECT_BRIEF = -PROJECT_LOGO = ../../logo.png +PROJECT_LOGO = ../../assets/logo.png OUTPUT_DIRECTORY = doc/ CREATE_SUBDIRS = NO ALLOW_UNICODE_NAMES = NO diff --git a/lib/runtime-c-api/src/import/emscripten.rs b/lib/runtime-c-api/src/import/emscripten.rs index 83777a762..7fa8a5f15 100644 --- a/lib/runtime-c-api/src/import/emscripten.rs +++ b/lib/runtime-c-api/src/import/emscripten.rs @@ -127,7 +127,7 @@ pub unsafe extern "C" fn wasmer_emscripten_call_main( /// `wasmer_emscripten_globals_t` from a `wasmer_module_t`. /// /// WARNING: -///1 +/// /// This `import_object_t` contains thin-wrappers around host system calls. /// Do not use this to execute untrusted code without additional sandboxing. #[no_mangle] diff --git a/lib/runtime-core-tests/Cargo.toml b/lib/runtime-core-tests/Cargo.toml index cb6d6b25c..8697caada 100644 --- a/lib/runtime-core-tests/Cargo.toml +++ b/lib/runtime-core-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-runtime-core-tests" -version = "0.14.0" +version = "0.14.1" description = "Tests for the Wasmer runtime core crate" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -9,10 +9,10 @@ publish = false [dependencies] wabt = "0.9.1" -wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" } -wasmer-clif-backend = { path = "../clif-backend", version = "0.14.0", optional = true } -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.0", optional = true } -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.0", features = ["test"], optional = true } +wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" } +wasmer-clif-backend = { path = "../clif-backend", version = "0.14.1", optional = true } +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.1", optional = true } +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.1", features = ["test"], optional = true } [features] default = ["backend-cranelift"] diff --git a/lib/runtime-core/Cargo.toml b/lib/runtime-core/Cargo.toml index 1cdd09526..ef7db2e80 100644 --- a/lib/runtime-core/Cargo.toml +++ b/lib/runtime-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-runtime-core" -version = "0.14.0" +version = "0.14.1" description = "Wasmer runtime core library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -12,7 +12,7 @@ edition = "2018" [dependencies] nix = "0.15" page_size = "0.4" -wasmparser = "0.45.0" +wasmparser = "0.51.3" parking_lot = "0.10.0" lazy_static = "1.4" errno = "0.2" diff --git a/lib/runtime-core/README.md b/lib/runtime-core/README.md index fafbcd85b..579143b7a 100644 --- a/lib/runtime-core/README.md +++ b/lib/runtime-core/README.md @@ -1,6 +1,6 @@

- Wasmer logo + Wasmer logo

diff --git a/lib/runtime-core/src/codegen.rs b/lib/runtime-core/src/codegen.rs index eed5d51e8..b65234cf4 100644 --- a/lib/runtime-core/src/codegen.rs +++ b/lib/runtime-core/src/codegen.rs @@ -275,8 +275,8 @@ fn validate_with_features(bytes: &[u8], features: &Features) -> CompileResult<() let state = parser.read(); match *state { wasmparser::ParserState::EndWasm => break Ok(()), - wasmparser::ParserState::Error(err) => Err(CompileError::ValidationError { - msg: err.message.to_string(), + wasmparser::ParserState::Error(ref err) => Err(CompileError::ValidationError { + msg: err.message().to_string(), })?, _ => {} } diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index 2dc226ccc..7b6168c5f 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -169,7 +169,7 @@ pub fn validate_and_report_errors_with_features( let state = parser.read(); match *state { wasmparser::ParserState::EndWasm => break Ok(()), - wasmparser::ParserState::Error(e) => break Err(format!("{}", e)), + wasmparser::ParserState::Error(ref e) => break Err(format!("{}", e)), _ => {} } } diff --git a/lib/runtime-core/src/parse.rs b/lib/runtime-core/src/parse.rs index 0226a9712..8189e33f0 100644 --- a/lib/runtime-core/src/parse.rs +++ b/lib/runtime-core/src/parse.rs @@ -21,15 +21,15 @@ use std::collections::HashMap; use std::fmt::Debug; use std::sync::{Arc, RwLock}; use wasmparser::{ - BinaryReaderError, ExternalKind, FuncType, ImportSectionEntryType, Operator, Type as WpType, - WasmDecoder, + BinaryReaderError, ElemSectionEntryTable, ElementItem, ExternalKind, FuncType, + ImportSectionEntryType, Operator, Type as WpType, WasmDecoder, }; /// Kind of load error. #[derive(Debug)] pub enum LoadError { /// Parse error. - Parse(BinaryReaderError), + Parse(String), /// Code generation error. Codegen(String), } @@ -44,7 +44,13 @@ impl From for CompileError { impl From for LoadError { fn from(other: BinaryReaderError) -> LoadError { - LoadError::Parse(other) + LoadError::Parse(format!("{:?}", other)) + } +} + +impl From<&BinaryReaderError> for LoadError { + fn from(other: &BinaryReaderError) -> LoadError { + LoadError::Parse(format!("{:?}", other)) } } @@ -110,7 +116,7 @@ pub fn read_module< use wasmparser::ParserState; let state = parser.read(); match *state { - ParserState::Error(err) => Err(LoadError::Parse(err))?, + ParserState::Error(ref err) => return Err(err.clone().into()), ParserState::TypeSectionEntry(ref ty) => { info.write() .unwrap() @@ -314,15 +320,18 @@ pub fn read_module< .map_err(|x| LoadError::Codegen(format!("{:?}", x)))?; func_count = func_count.wrapping_add(1); } - ParserState::BeginActiveElementSectionEntry(table_index) => { - let table_index = TableIndex::new(table_index as usize); + ParserState::BeginElementSectionEntry { + table: ElemSectionEntryTable::Active(table_index_raw), + ty: WpType::AnyFunc, + } => { + let table_index = TableIndex::new(table_index_raw as usize); let mut elements: Option> = None; let mut base: Option = None; loop { let state = parser.read(); match *state { - ParserState::Error(err) => return Err(LoadError::Parse(err)), + ParserState::Error(ref err) => return Err(err.into()), ParserState::InitExpressionOperator(ref op) => { base = Some(eval_init_expr(op)?) } @@ -330,9 +339,11 @@ pub fn read_module< elements = Some( _elements .iter() - .cloned() - .map(|index| FuncIndex::new(index as usize)) - .collect(), + .map(|elem_idx| match elem_idx { + ElementItem::Null => Err(LoadError::Parse(format!("Error at table {}: null entries in tables are not yet supported", table_index_raw))), + ElementItem::Func(idx) => Ok(FuncIndex::new(*idx as usize)), + }) + .collect::, LoadError>>()?, ); } ParserState::BeginInitExpressionBody @@ -350,6 +361,15 @@ pub fn read_module< info.write().unwrap().elem_initializers.push(table_init); } + ParserState::BeginElementSectionEntry { + table: ElemSectionEntryTable::Active(table_index), + ty, + } => { + return Err(LoadError::Parse(format!( + "Error at table {}: type \"{:?}\" is not supported in tables yet", + table_index, ty + ))); + } ParserState::BeginActiveDataSectionEntry(memory_index) => { let memory_index = MemoryIndex::new(memory_index as usize); let mut base: Option = None; @@ -358,7 +378,7 @@ pub fn read_module< loop { let state = parser.read(); match *state { - ParserState::Error(err) => return Err(LoadError::Parse(err)), + ParserState::Error(ref err) => return Err(err.into()), ParserState::InitExpressionOperator(ref op) => { base = Some(eval_init_expr(op)?) } @@ -385,7 +405,7 @@ pub fn read_module< let init = loop { let state = parser.read(); match *state { - ParserState::Error(err) => return Err(LoadError::Parse(err)), + ParserState::Error(ref err) => return Err(err.into()), ParserState::InitExpressionOperator(ref op) => { break eval_init_expr(op)?; } @@ -424,7 +444,7 @@ pub fn read_module< } /// Convert given `WpType` to `Type`. -pub fn wp_type_to_type(ty: WpType) -> Result { +pub fn wp_type_to_type(ty: WpType) -> Result { match ty { WpType::I32 => Ok(Type::I32), WpType::I64 => Ok(Type::I64), @@ -432,10 +452,9 @@ pub fn wp_type_to_type(ty: WpType) -> Result { WpType::F64 => Ok(Type::F64), WpType::V128 => Ok(Type::V128), _ => { - return Err(BinaryReaderError { - message: "broken invariant, invalid type", - offset: -1isize as usize, - }); + return Err(LoadError::Parse( + "broken invariant, invalid type".to_string(), + )); } } } @@ -451,7 +470,7 @@ pub fn type_to_wp_type(ty: Type) -> WpType { } } -fn func_type_to_func_sig(func_ty: &FuncType) -> Result { +fn func_type_to_func_sig(func_ty: &FuncType) -> Result { assert_eq!(func_ty.form, WpType::Func); Ok(FuncSig::new( @@ -470,7 +489,7 @@ fn func_type_to_func_sig(func_ty: &FuncType) -> Result Result { +fn eval_init_expr(op: &Operator) -> Result { Ok(match *op { Operator::GlobalGet { global_index } => { Initializer::GetGlobal(ImportedGlobalIndex::new(global_index as usize)) @@ -487,10 +506,9 @@ fn eval_init_expr(op: &Operator) -> Result { Initializer::Const(Value::V128(u128::from_le_bytes(*value.bytes()))) } _ => { - return Err(BinaryReaderError { - message: "init expr evaluation failed: unsupported opcode", - offset: -1isize as usize, - }); + return Err(LoadError::Parse( + "init expr evaluation failed: unsupported opcode".to_string(), + )); } }) } diff --git a/lib/runtime/Cargo.toml b/lib/runtime/Cargo.toml index bd4194cf6..f9c6ec31a 100644 --- a/lib/runtime/Cargo.toml +++ b/lib/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-runtime" -version = "0.14.0" +version = "0.14.1" description = "Wasmer runtime library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -11,17 +11,17 @@ edition = "2018" readme = "README.md" [dependencies] -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.0", optional = true } +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.1", optional = true } lazy_static = "1.4" memmap = "0.7" [dependencies.wasmer-runtime-core] path = "../runtime-core" -version = "0.14.0" +version = "0.14.1" [dependencies.wasmer-clif-backend] path = "../clif-backend" -version = "0.14.0" +version = "0.14.1" optional = true # Dependencies for caching. diff --git a/lib/runtime/README.md b/lib/runtime/README.md index ce18500bf..08bec247f 100644 --- a/lib/runtime/README.md +++ b/lib/runtime/README.md @@ -1,6 +1,6 @@

- Wasmer logo + Wasmer logo

diff --git a/lib/singlepass-backend/Cargo.toml b/lib/singlepass-backend/Cargo.toml index e86c36ab2..e86e0b8d1 100644 --- a/lib/singlepass-backend/Cargo.toml +++ b/lib/singlepass-backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-singlepass-backend" -version = "0.14.0" +version = "0.14.1" repository = "https://github.com/wasmerio/wasmer" description = "Wasmer runtime single pass compiler backend" license = "MIT" @@ -11,7 +11,7 @@ edition = "2018" readme = "README.md" [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" } dynasm = "0.5" dynasmrt = "0.5" lazy_static = "1.4" diff --git a/lib/singlepass-backend/README.md b/lib/singlepass-backend/README.md index cf9ee566c..c7f35f814 100644 --- a/lib/singlepass-backend/README.md +++ b/lib/singlepass-backend/README.md @@ -1,6 +1,6 @@

- Wasmer logo + Wasmer logo

diff --git a/lib/spectests/Cargo.toml b/lib/spectests/Cargo.toml index d5bdd9717..7d88e3e7a 100644 --- a/lib/spectests/Cargo.toml +++ b/lib/spectests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-spectests" -version = "0.14.0" +version = "0.14.1" description = "Wasmer spectests library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -9,10 +9,10 @@ edition = "2018" [dependencies] glob = "0.3" -wasmer-runtime = { path = "../runtime", version = "0.14.0", default-features = false} -wasmer-clif-backend = { path = "../clif-backend", version = "0.14.0", optional = true} -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.0", features = ["test"], optional = true } -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.0", optional = true } +wasmer-runtime = { path = "../runtime", version = "0.14.1", default-features = false} +wasmer-clif-backend = { path = "../clif-backend", version = "0.14.1", optional = true} +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.1", features = ["test"], optional = true } +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.1", optional = true } [build-dependencies] wabt = "0.9.1" diff --git a/lib/spectests/README.md b/lib/spectests/README.md index da05683ea..c5a9486a6 100644 --- a/lib/spectests/README.md +++ b/lib/spectests/README.md @@ -1,6 +1,6 @@

- Wasmer logo + Wasmer logo

diff --git a/lib/spectests/tests/excludes.txt b/lib/spectests/tests/excludes.txt index b6690cc99..8d1ccdaa7 100644 --- a/lib/spectests/tests/excludes.txt +++ b/lib/spectests/tests/excludes.txt @@ -267,10 +267,6 @@ clif:fail:data.wast:186:windows # AssertUnlinkable - caught panic Any clif:fail:data.wast:194:windows # AssertUnlinkable - caught panic Any # LLVM -llvm:fail:f32.wast:1621 # AssertReturn - result F32(0) ("0x0") does not match expected F32(2147483648) ("0x80000000") -llvm:fail:f32.wast:2020 # AssertReturn - result F32(2147483648) ("0x80000000") does not match expected F32(0) ("0x0") -llvm:fail:f64.wast:1621 # AssertReturn - result F64(0) ("0x0") does not match expected F64(9223372036854775808) ("0x8000000000000000") -llvm:fail:f64.wast:2020 # AssertReturn - result F64(9223372036854775808) ("0x8000000000000000") does not match expected F64(0) ("0x0") llvm:fail:linking.wast:388 # AssertReturn - Call failed RuntimeError: WebAssembly trap occurred during runtime: incorrect `call_indirect` signature # LLVM AArch64 @@ -312,48 +308,65 @@ singlepass:skip:simd_binaryen.wast:* # SIMD not implemented singlepass:skip:atomic.wast:*:*:aarch64 # Threads not yet supported on singlepass -singlepass:fail:address.wast:194 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:195 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:196 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:197 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:198 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:200 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:201 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:202 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:203 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:204 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:481 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:482 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:483 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:484 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:485 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:486 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:487 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:489 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:490 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:491 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:492 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:493 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:494 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:495 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:541 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:542 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:588 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:589 # AssertTrap - expected trap, got [] -singlepass:fail:globals.wast:243 # AssertInvalid - Should be invalid -singlepass:fail:linking.wast:134 # AssertReturn - Call failed RuntimeError: unknown error -singlepass:fail:linking.wast:137 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:139 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:142 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:144 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:147 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:149 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:169 # AssertReturn - Call failed RuntimeError: unknown error -singlepass:fail:linking.wast:175 # AssertReturn - Call failed RuntimeError: unknown error -singlepass:fail:linking.wast:181 # AssertReturn - Call failed RuntimeError: unknown error -singlepass:fail:linking.wast:185 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:187 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:388 # AssertReturn - Call failed RuntimeError: unknown error +singlepass:fail:address.wast:200:linux:x86_64 # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:201:linux:x86_64 # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:202:linux:x86_64 # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:203:linux:x86_64 # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:204:linux:x86_64 # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:489:linux:x86_64 # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:490:linux:x86_64 # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:491:linux:x86_64 # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:492:linux:x86_64 # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:495:linux:x86_64 # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:542:linux:x86_64 # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:589:linux:x86_64 # AssertTrap - expected trap, got [] +singlepass:fail:linking.wast:137:linux # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:139:linux # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:142:linux # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:144:linux # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:147:linux # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:149:linux # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:185:linux # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:187:linux # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:388:linux # AssertReturn - Call failed RuntimeError: unknown error + +singlepass:fail:address.wast:194:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:195:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:196:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:197:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:198:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:200:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:201:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:202:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:203:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:204:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:481:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:482:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:483:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:484:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:485:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:486:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:487:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:489:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:490:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:491:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:492:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:493:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:494:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:495:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:541:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:542:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:588:macos # AssertTrap - expected trap, got [] +singlepass:fail:address.wast:589:macos # AssertTrap - expected trap, got [] +singlepass:fail:linking.wast:137:macos # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:139:macos # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:142:macos # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:144:macos # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:147:macos # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:149:macos # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:185:macos # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:187:macos # AssertTrap - expected trap, got Runtime:Error unknown error +singlepass:fail:linking.wast:388:macos # AssertReturn - Call failed RuntimeError: unknown error # These failures only happen on AArch64 and not on x86-64. singlepass:fail:conversions.wast:83:*:aarch64 # AssertTrap - expected trap, got [I32(2147483647)] diff --git a/lib/spectests/tests/spectest.rs b/lib/spectests/tests/spectest.rs index f8b7939f3..f958f1258 100644 --- a/lib/spectests/tests/spectest.rs +++ b/lib/spectests/tests/spectest.rs @@ -48,12 +48,21 @@ mod tests { &mut self, failure: SpecFailure, _testkey: &str, - excludes: &Vec, + excludes: &mut Vec>, line: u64, ) { - if excludes - .iter() - .any(|e| e.line_matches(line) && e.exclude_kind == ExcludeKind::Fail) + // Ensure that each exclude is only used once. + if let Some(_) = excludes + .iter_mut() + .find(|e| { + if let Some(ref e) = e { + e.line_matches(line) && e.exclude_kind == ExcludeKind::Fail + } else { + false + } + }) + .take() + .and_then(|x| x.take()) { self.allowed_failure += 1; return; @@ -88,6 +97,21 @@ mod tests { "windows" } + #[cfg(target_os = "linux")] + fn get_target_os() -> &'static str { + "linux" + } + + #[cfg(target_os = "macos")] + fn get_target_os() -> &'static str { + "macos" + } + + #[cfg(target_os = "windows")] + fn get_target_os() -> &'static str { + "windows" + } + fn get_target_arch() -> &'static str { if cfg!(target_arch = "x86_64") { "x86_64" @@ -110,6 +134,7 @@ mod tests { // clif:skip:data.wast:172:unix:x86 #[allow(dead_code)] + #[derive(Clone)] struct Exclude { backend: Option, exclude_kind: ExcludeKind, @@ -261,13 +286,11 @@ mod tests { let mut named_modules: HashMap>> = HashMap::new(); let mut registered_modules: HashMap>> = HashMap::new(); - // - let empty_excludes = vec![]; - let excludes = if excludes.contains_key(filename) { - excludes.get(filename).unwrap() - } else { - &empty_excludes - }; + let mut excludes: Vec<_> = excludes + .get(filename) + .map(|file| file.iter().map(|x| Some(x.clone())).collect()) + .unwrap_or(vec![]); + let excludes = &mut excludes; let backend = get_compiler_name(); @@ -281,6 +304,7 @@ mod tests { // Skip tests that match this line if excludes .iter() + .filter_map(|x| x.as_ref()) .any(|e| e.line_exact_match(line) && e.exclude_kind == ExcludeKind::Skip) { continue; @@ -1074,6 +1098,21 @@ mod tests { }, } } + + // Check for unused excludes. + for excl in excludes { + if let Some(ref excl) = *excl { + if excl.exclude_kind == ExcludeKind::Fail { + test_report.failed += 1; + test_report.failures.push(SpecFailure { + file: filename.to_string(), + line: excl.line.unwrap_or(0), + kind: format!("{}", "Exclude"), + message: format!("Excluded failure did not occur"), + }); + } + } + } Ok(test_report) } @@ -1235,6 +1274,7 @@ mod tests { let mut result = HashMap::new(); let mut file_excludes = HashSet::new(); let current_backend = get_compiler_name(); + let current_target_os = get_target_os(); let current_target_family = get_target_family(); let current_target_arch = get_target_arch(); @@ -1283,7 +1323,8 @@ mod tests { }; if exclude.matches_backend(current_backend) - && exclude.matches_target_family(current_target_family) + && (exclude.matches_target_family(current_target_os) + || exclude.matches_target_family(current_target_family)) && exclude.matches_target_arch(current_target_arch) { // Skip the whole file for line * and skip diff --git a/lib/wasi-experimental-io-devices/Cargo.toml b/lib/wasi-experimental-io-devices/Cargo.toml index bbce57713..d29d30379 100644 --- a/lib/wasi-experimental-io-devices/Cargo.toml +++ b/lib/wasi-experimental-io-devices/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-wasi-experimental-io-devices" -version = "0.14.0" +version = "0.14.1" authors = ["The Wasmer Engineering Team "] edition = "2018" repository = "https://github.com/wasmerio/wasmer" @@ -14,8 +14,8 @@ maintenance = { status = "experimental" } [dependencies] log = "0.4" minifb = "0.13" -wasmer-wasi = { version = "0.14.0", path = "../wasi" } -wasmer-runtime-core = { version = "0.14.0", path = "../runtime-core" } +wasmer-wasi = { version = "0.14.1", path = "../wasi" } +wasmer-runtime-core = { version = "0.14.1", path = "../runtime-core" } ref_thread_local = "0.0" serde = "1" typetag = "0.1" diff --git a/lib/wasi-tests/Cargo.toml b/lib/wasi-tests/Cargo.toml index b4fa7915b..e93d4d9cd 100644 --- a/lib/wasi-tests/Cargo.toml +++ b/lib/wasi-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-wasi-tests" -version = "0.14.0" +version = "0.14.1" description = "Tests for our WASI implementation" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -10,18 +10,18 @@ build = "build/mod.rs" [dependencies] # We set default features to false to be able to use the singlepass backend properly -wasmer-runtime = { path = "../runtime", version = "0.14.0", default-features = false } -wasmer-wasi = { path = "../wasi", version = "0.14.0" } +wasmer-runtime = { path = "../runtime", version = "0.14.1", default-features = false } +wasmer-wasi = { path = "../wasi", version = "0.14.1" } # hack to get tests to work -wasmer-clif-backend = { path = "../clif-backend", version = "0.14.0", optional = true} -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.0", optional = true } -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.0", features = ["test"], optional = true } +wasmer-clif-backend = { path = "../clif-backend", version = "0.14.1", optional = true} +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.1", optional = true } +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.1", features = ["test"], optional = true } [build-dependencies] glob = "0.3" [dev-dependencies] -wasmer-dev-utils = { path = "../dev-utils", version = "0.14.0"} +wasmer-dev-utils = { path = "../dev-utils", version = "0.14.1"} [features] clif = ["wasmer-clif-backend", "wasmer-runtime/default-backend-cranelift"] diff --git a/lib/wasi/Cargo.toml b/lib/wasi/Cargo.toml index 4dd5a6dbf..ce7669475 100644 --- a/lib/wasi/Cargo.toml +++ b/lib/wasi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-wasi" -version = "0.14.0" +version = "0.14.1" description = "Wasmer runtime WASI implementation library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -19,7 +19,7 @@ getrandom = "0.1" time = "0.1" typetag = "0.1" serde = { version = "1", features = ["derive"] } -wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" } [target.'cfg(windows)'.dependencies] winapi = "0.3" diff --git a/lib/win-exception-handler/Cargo.toml b/lib/win-exception-handler/Cargo.toml index 95504170a..a221815a7 100644 --- a/lib/win-exception-handler/Cargo.toml +++ b/lib/win-exception-handler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-win-exception-handler" -version = "0.14.0" +version = "0.14.1" description = "Wasmer runtime exception handling for Windows" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -8,7 +8,7 @@ repository = "https://github.com/wasmerio/wasmer" edition = "2018" [target.'cfg(windows)'.dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" } winapi = { version = "0.3.8", features = ["winbase", "errhandlingapi", "minwindef", "minwinbase", "winnt"] } libc = "0.2.60" diff --git a/lib/win-exception-handler/README.md b/lib/win-exception-handler/README.md index 351228d04..a5f6e25ce 100644 --- a/lib/win-exception-handler/README.md +++ b/lib/win-exception-handler/README.md @@ -1,6 +1,6 @@

- Wasmer logo + Wasmer logo

diff --git a/scripts/update_version_numbers.sh b/scripts/update_version_numbers.sh index 21e6cdd66..9fd20ae24 100755 --- a/scripts/update_version_numbers.sh +++ b/scripts/update_version_numbers.sh @@ -1,5 +1,5 @@ -PREVIOUS_VERSION='0.13.1' -NEXT_VERSION='0.14.0' +PREVIOUS_VERSION='0.14.0' +NEXT_VERSION='0.14.1' # quick hack fd Cargo.toml --exec sed -i '' "s/version = \"$PREVIOUS_VERSION\"/version = \"$NEXT_VERSION\"/" diff --git a/src/installer/wasmer.iss b/src/installer/wasmer.iss index 0ddf11414..3bb42cacd 100644 --- a/src/installer/wasmer.iss +++ b/src/installer/wasmer.iss @@ -1,6 +1,6 @@ [Setup] AppName=Wasmer -AppVersion=0.14.0 +AppVersion=0.14.1 DefaultDirName={pf}\Wasmer DefaultGroupName=Wasmer Compression=lzma2