From ad70caff8389fe7d7018603de58e421cb7f2c07f Mon Sep 17 00:00:00 2001 From: Johan Andersson Date: Sun, 15 Sep 2019 03:21:04 +0200 Subject: [PATCH 01/49] Remove colored CLI output from runtime-core lib. When the colored output was originally added in https://github.com/wasmerio/wasmer/pull/489 and there was a discussion then about that it should ideally be in a higher-level crate rather than in the runtime-core library crate. I agree with that, users of the library shouldn't be required to bring in the colored crate dependency and ideally also not have stdout/stderr output either, that should be controlled by the application that uses wasmer-runtime-core, not the library. Disabling stdout/stderr output would be more intrusive but I wanted to at least not have colored output and another crate dependency so this change removes the colored output and the "colored" crate. --- Cargo.lock | 69 ------------------------------- lib/runtime-core/Cargo.toml | 1 - lib/runtime-core/src/fault.rs | 3 -- lib/runtime-core/src/state.rs | 22 ++++------ lib/singlepass-backend/Cargo.toml | 1 - src/bin/wasmer.rs | 2 +- 6 files changed, 10 insertions(+), 88 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11c8633e316..9f2bdaf5a69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,11 +16,6 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "approx" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "arrayref" version = "0.3.5" @@ -205,16 +200,6 @@ name = "cfg-if" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "cgmath" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "clang-sys" version = "0.28.1" @@ -255,15 +240,6 @@ dependencies = [ "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "colored" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "constant_time_eq" version = "0.1.4" @@ -810,14 +786,6 @@ dependencies = [ "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "num-traits" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "num-traits" version = "0.2.8" @@ -947,18 +915,6 @@ dependencies = [ "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rand" version = "0.7.0" @@ -1108,11 +1064,6 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rgb" -version = "0.8.14" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "rustc-demangle" version = "0.1.16" @@ -1691,7 +1642,6 @@ dependencies = [ "bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "blake2b_simd 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1717,7 +1667,6 @@ name = "wasmer-singlepass-backend" version = "0.7.0" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "dynasm 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "dynasmrt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1843,21 +1792,9 @@ dependencies = [ "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "winconsole" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rgb 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [metadata] "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" @@ -1879,12 +1816,10 @@ dependencies = [ "checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be" "checksum cexpr 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7fa24eb00d5ffab90eaeaf1092ac85c04c64aaf358ea6f84505b8116d24c6af" "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" -"checksum cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c" "checksum clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" -"checksum colored 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cdb90b60f2927f8d76139c72dbde7e10c3a2bc47c8594c9c7a66529f2687c03" "checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" "checksum cranelift-bforest 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "409f92af3dd276e112b72873a3ef02613e3c5f55b81d5d5d04f3157d4f8b8c54" "checksum cranelift-codegen 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b303542a56fba4cbaeea099fb30ed078b50de0e765fd69f7f5f410adbe31d95b" @@ -1946,7 +1881,6 @@ dependencies = [ "checksum nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" @@ -1963,7 +1897,6 @@ dependencies = [ "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" -"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" @@ -1981,7 +1914,6 @@ dependencies = [ "checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" -"checksum rgb 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2089e4031214d129e201f8c3c8c2fe97cd7322478a0d1cdf78e7029b0042efdb" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" @@ -2043,4 +1975,3 @@ dependencies = [ "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9" -"checksum winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ef84b96d10db72dd980056666d7f1e7663ce93d82fa33b63e71c966f4cf5032" diff --git a/lib/runtime-core/Cargo.toml b/lib/runtime-core/Cargo.toml index 8ce52ebe048..9349a7c6407 100644 --- a/lib/runtime-core/Cargo.toml +++ b/lib/runtime-core/Cargo.toml @@ -18,7 +18,6 @@ libc = "0.2.60" hex = "0.3.2" smallvec = "0.6.10" bincode = "1.1" -colored = "1.8" [dependencies.indexmap] version = "1.2.0" diff --git a/lib/runtime-core/src/fault.rs b/lib/runtime-core/src/fault.rs index 2d46d8ca25c..a1a1f58c2f5 100644 --- a/lib/runtime-core/src/fault.rs +++ b/lib/runtime-core/src/fault.rs @@ -283,13 +283,10 @@ extern "C" fn signal_trap_handler( let image = build_instance_image(ctx, es_image); unwind_result = Box::new(image); } else { - use colored::*; if es_image.frames.len() > 0 { eprintln!( "\n{}", "Wasmer encountered an error while running your WebAssembly program." - .bold() - .red() ); es_image.print_backtrace_if_needed(); } diff --git a/lib/runtime-core/src/state.rs b/lib/runtime-core/src/state.rs index b6bbb95f50d..4da5283d791 100644 --- a/lib/runtime-core/src/state.rs +++ b/lib/runtime-core/src/state.rs @@ -303,7 +303,7 @@ impl ExecutionStateImage { if let Ok(x) = env::var("WASMER_BACKTRACE") { if x == "1" { - eprintln!("{}", self.colored_output()); + eprintln!("{}", self.output()); return; } } @@ -311,9 +311,7 @@ impl ExecutionStateImage { eprintln!("Run with `WASMER_BACKTRACE=1` environment variable to display a backtrace."); } - pub fn colored_output(&self) -> String { - use colored::*; - + pub fn output(&self) -> String { fn join_strings(x: impl Iterator, sep: &str) -> String { let mut ret = String::new(); let mut first = true; @@ -341,8 +339,6 @@ impl ExecutionStateImage { i, x.map(|x| format!("{}", x)) .unwrap_or_else(|| "?".to_string()) - .bold() - .cyan() ) }), ", ", @@ -353,27 +349,27 @@ impl ExecutionStateImage { let mut ret = String::new(); if self.frames.len() == 0 { - ret += &"Unknown fault address, cannot read stack.".yellow(); + ret += &"Unknown fault address, cannot read stack."; ret += "\n"; } else { - ret += &"Backtrace:".bold(); + ret += &"Backtrace:"; ret += "\n"; for (i, f) in self.frames.iter().enumerate() { - ret += &format!("* Frame {} @ Local function {}", i, f.local_function_id).bold(); + ret += &format!("* Frame {} @ Local function {}", i, f.local_function_id); ret += "\n"; ret += &format!( " {} {}\n", - "Offset:".bold().yellow(), - format!("{}", f.wasm_inst_offset).bold().cyan(), + "Offset:", + format!("{}", f.wasm_inst_offset), ); ret += &format!( " {} {}\n", - "Locals:".bold().yellow(), + "Locals:", format_optional_u64_sequence(&f.locals) ); ret += &format!( " {} {}\n\n", - "Stack:".bold().yellow(), + "Stack:", format_optional_u64_sequence(&f.stack) ); } diff --git a/lib/singlepass-backend/Cargo.toml b/lib/singlepass-backend/Cargo.toml index fd649456953..65bfd54bcc7 100644 --- a/lib/singlepass-backend/Cargo.toml +++ b/lib/singlepass-backend/Cargo.toml @@ -18,4 +18,3 @@ byteorder = "1.3.2" nix = "0.15.0" libc = "0.2.60" smallvec = "0.6.10" -colored = "1.8" diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index f9cffd1ae2e..659f53c715f 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -732,7 +732,7 @@ fn interactive_shell(mut ctx: InteractiveShellContext) -> ShellExitOperation { } "backtrace" | "bt" => { if let Some(ref image) = ctx.image { - println!("{}", image.execution_state.colored_output()); + println!("{}", image.execution_state.output()); } else { println!("State not available"); } From 21bcac21591366b2a1fbe39d53d9863b1ad4d6f7 Mon Sep 17 00:00:00 2001 From: Johan Andersson Date: Sun, 15 Sep 2019 03:31:05 +0200 Subject: [PATCH 02/49] Rustfmt --- lib/runtime-core/src/state.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/runtime-core/src/state.rs b/lib/runtime-core/src/state.rs index 4da5283d791..7b8dcd2b1c9 100644 --- a/lib/runtime-core/src/state.rs +++ b/lib/runtime-core/src/state.rs @@ -357,11 +357,7 @@ impl ExecutionStateImage { for (i, f) in self.frames.iter().enumerate() { ret += &format!("* Frame {} @ Local function {}", i, f.local_function_id); ret += "\n"; - ret += &format!( - " {} {}\n", - "Offset:", - format!("{}", f.wasm_inst_offset), - ); + ret += &format!(" {} {}\n", "Offset:", format!("{}", f.wasm_inst_offset),); ret += &format!( " {} {}\n", "Locals:", From b35a522d28628ab0fd1b4a978358f898096d8aee Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Mon, 16 Sep 2019 15:01:18 -0700 Subject: [PATCH 03/49] Add method to call function at index on Ctx --- lib/runtime-core/src/instance.rs | 2 +- lib/runtime-core/src/vm.rs | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index e6ba365f6ef..97b2d362927 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -518,7 +518,7 @@ impl LikeNamespace for Rc { } #[must_use] -fn call_func_with_index( +pub(crate) fn call_func_with_index( info: &ModuleInfo, runnable: &dyn RunnableModule, import_backing: &ImportBacking, diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 51f883318d1..7c811e36ecf 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -1,9 +1,11 @@ pub use crate::backing::{ImportBacking, LocalBacking, INTERNALS_SIZE}; use crate::{ + error::{CallError, CallResult, RuntimeError}, + instance::call_func_with_index, memory::{Memory, MemoryType}, module::{ModuleInfo, ModuleInner}, structures::TypedIndex, - types::{LocalOrImport, MemoryIndex}, + types::{FuncIndex, LocalOrImport, MemoryIndex, Value}, vmcalls, }; use std::{ @@ -393,6 +395,27 @@ impl Ctx { (*self.internal.internals)[field.index()] = value; } } + + /// Calls a host or Wasm function at the given index + pub fn call_with_index(&mut self, index: FuncIndex, args: &[Value]) -> CallResult> { + let module = unsafe { &(*self.module) }; + if module.info.func_assoc.get(index).is_none() { + return Err(CallError::Runtime(RuntimeError::Trap { + msg: format!("Index out of bounds: {}", index.index()).into_boxed_str(), + })); + } + let mut output = vec![]; + call_func_with_index( + &module.info, + module.runnable_module.as_ref(), + unsafe { &*self.import_backing }, + self as *mut Ctx, + index, + args, + &mut output, + )?; + Ok(output) + } } #[doc(hidden)] From 4190f011957c8f73d6c8c14ef8d9bfecb0b81fd5 Mon Sep 17 00:00:00 2001 From: Patrick Ventuzelo Date: Tue, 17 Sep 2019 12:03:03 +0200 Subject: [PATCH 04/49] remove panic and unimplemented in llvm-backend and runtime-core --- lib/llvm-backend/src/code.rs | 28 +++++++++++++++++++++++----- lib/llvm-backend/src/trampolines.rs | 14 +++++++++----- lib/runtime-core/src/parse.rs | 21 +++++++++++++-------- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/lib/llvm-backend/src/code.rs b/lib/llvm-backend/src/code.rs index 2696d2896c6..8ac76fe269b 100644 --- a/lib/llvm-backend/src/code.rs +++ b/lib/llvm-backend/src/code.rs @@ -1176,7 +1176,11 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { BasicTypeEnum::FloatType(float_ty) => { float_ty.const_float(0.0).as_basic_value_enum() } - _ => unimplemented!(), + _ => { + return Err(CodegenError { + message: "Operator::End phi type unimplemented".to_string(), + }); + } }; state.push1(placeholder_value); phi.as_instruction().erase_from_basic_block(); @@ -1741,7 +1745,12 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { _ => value, }); } - _ => unimplemented!("multi-value returns"), + _ => { + return Err(CodegenError { + message: "Operator::CallIndirect multi-value returns unimplemented" + .to_string(), + }); + } } } @@ -6853,7 +6862,9 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { state.push1(result.try_as_basic_value().left().unwrap()); } _ => { - unimplemented!("{:?}", op); + return Err(CodegenError { + message: format!("Operator {:?} unimplemented", op), + }); } } @@ -6876,7 +6887,11 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { "return", ))); } - _ => unimplemented!("multi-value returns not yet implemented"), + _ => { + return Err(CodegenError { + message: "multi-value returns not yet implemented".to_string(), + }); + } } Ok(()) } @@ -7051,7 +7066,10 @@ impl ModuleCodeGenerator self.context.as_ref().unwrap(), self.builder.as_ref().unwrap(), self.intrinsics.as_ref().unwrap(), - ); + ) + .map_err(|e| CodegenError { + message: format!("trampolines generation error: {:?}", e), + })?; if let Some(path) = unsafe { &crate::GLOBAL_OPTIONS.pre_opt_ir } { self.module.print_to_file(path).unwrap(); diff --git a/lib/llvm-backend/src/trampolines.rs b/lib/llvm-backend/src/trampolines.rs index cebfa9d4671..c75438d2331 100644 --- a/lib/llvm-backend/src/trampolines.rs +++ b/lib/llvm-backend/src/trampolines.rs @@ -20,7 +20,7 @@ pub fn generate_trampolines( context: &Context, builder: &Builder, intrinsics: &Intrinsics, -) { +) -> Result<(), String> { for (sig_index, sig) in info.signatures.iter() { let func_type = signatures[sig_index]; @@ -42,8 +42,9 @@ pub fn generate_trampolines( Some(Linkage::External), ); - generate_trampoline(trampoline_func, sig, context, builder, intrinsics); + generate_trampoline(trampoline_func, sig, context, builder, intrinsics)?; } + Ok(()) } fn generate_trampoline( @@ -52,7 +53,7 @@ fn generate_trampoline( context: &Context, builder: &Builder, intrinsics: &Intrinsics, -) { +) -> Result<(), String> { let entry_block = context.append_basic_block(&trampoline_func, "entry"); builder.position_at_end(&entry_block); @@ -64,7 +65,7 @@ fn generate_trampoline( args_ptr.into_pointer_value(), returns_ptr.into_pointer_value(), ), - _ => unimplemented!(), + _ => return Err("trampoline function unimplemented".to_string()), }; let cast_ptr_ty = |wasmer_ty| match wasmer_ty { @@ -108,8 +109,11 @@ fn generate_trampoline( call_site.try_as_basic_value().left().unwrap(), ); } - _ => unimplemented!("multi-value returns"), + _ => { + return Err("trampoline function multi-value returns".to_string()); + } } builder.build_return(None); + Ok(()) } diff --git a/lib/runtime-core/src/parse.rs b/lib/runtime-core/src/parse.rs index 259a628dd74..b2ad3051e6c 100644 --- a/lib/runtime-core/src/parse.rs +++ b/lib/runtime-core/src/parse.rs @@ -392,14 +392,19 @@ pub fn read_module< } pub fn wp_type_to_type(ty: WpType) -> Result { - Ok(match ty { - WpType::I32 => Type::I32, - WpType::I64 => Type::I64, - WpType::F32 => Type::F32, - WpType::F64 => Type::F64, - WpType::V128 => Type::V128, - _ => panic!("broken invariant, invalid type"), - }) + match ty { + WpType::I32 => Ok(Type::I32), + WpType::I64 => Ok(Type::I64), + WpType::F32 => Ok(Type::F32), + WpType::F64 => Ok(Type::F64), + WpType::V128 => Ok(Type::V128), + _ => { + return Err(BinaryReaderError { + message: "broken invariant, invalid type", + offset: -1isize as usize, + }); + } + } } pub fn type_to_wp_type(ty: Type) -> WpType { From 726269a52cf709d1953fd25a6e2ff918b167237e Mon Sep 17 00:00:00 2001 From: Patrick Ventuzelo Date: Tue, 17 Sep 2019 12:05:00 +0200 Subject: [PATCH 05/49] fix missing info error --- lib/llvm-backend/src/trampolines.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/llvm-backend/src/trampolines.rs b/lib/llvm-backend/src/trampolines.rs index c75438d2331..c9bd50e1b47 100644 --- a/lib/llvm-backend/src/trampolines.rs +++ b/lib/llvm-backend/src/trampolines.rs @@ -110,7 +110,7 @@ fn generate_trampoline( ); } _ => { - return Err("trampoline function multi-value returns".to_string()); + return Err("trampoline function multi-value returns unimplemented".to_string()); } } From c660aa9fce1a15b62d12ac59738c3d030a804b4f Mon Sep 17 00:00:00 2001 From: Patrick Ventuzelo Date: Tue, 17 Sep 2019 17:42:06 +0200 Subject: [PATCH 06/49] fix 653 panic in memoryDescriptor --- lib/emscripten/src/lib.rs | 6 +----- lib/runtime-core/src/memory/mod.rs | 2 +- lib/runtime-core/src/parse.rs | 23 +++++++++++++---------- lib/runtime-core/src/types.rs | 24 +++++++++++++++++++----- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index ba25b4be82a..0d30c0b0b79 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -473,11 +473,7 @@ impl EmscriptenGlobals { let (memory_min, memory_max, shared) = get_emscripten_memory_size(&module)?; // Memory initialization - let memory_type = MemoryDescriptor { - minimum: memory_min, - maximum: memory_max, - shared: shared, - }; + let memory_type = MemoryDescriptor::new(memory_min, memory_max, shared)?; let memory = Memory::new(memory_type).unwrap(); let table_type = TableDescriptor { diff --git a/lib/runtime-core/src/memory/mod.rs b/lib/runtime-core/src/memory/mod.rs index 75e9ea007dc..6f6af5c65b4 100644 --- a/lib/runtime-core/src/memory/mod.rs +++ b/lib/runtime-core/src/memory/mod.rs @@ -177,7 +177,7 @@ impl fmt::Debug for Memory { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum MemoryType { Dynamic, Static, diff --git a/lib/runtime-core/src/parse.rs b/lib/runtime-core/src/parse.rs index 259a628dd74..9162c5169a6 100644 --- a/lib/runtime-core/src/parse.rs +++ b/lib/runtime-core/src/parse.rs @@ -136,11 +136,13 @@ pub fn read_module< .push((import_name, table_desc)); } ImportSectionEntryType::Memory(memory_ty) => { - let mem_desc = MemoryDescriptor { - minimum: Pages(memory_ty.limits.initial), - maximum: memory_ty.limits.maximum.map(|max| Pages(max)), - shared: memory_ty.shared, - }; + let mem_desc = MemoryDescriptor::new( + Pages(memory_ty.limits.initial), + memory_ty.limits.maximum.map(|max| Pages(max)), + memory_ty.shared, + ) + .map_err(|x| LoadError::Codegen(format!("{:?}", x)))?; + info.write() .unwrap() .imported_memories @@ -172,11 +174,12 @@ pub fn read_module< info.write().unwrap().tables.push(table_desc); } ParserState::MemorySectionEntry(memory_ty) => { - let mem_desc = MemoryDescriptor { - minimum: Pages(memory_ty.limits.initial), - maximum: memory_ty.limits.maximum.map(|max| Pages(max)), - shared: memory_ty.shared, - }; + let mem_desc = MemoryDescriptor::new( + Pages(memory_ty.limits.initial), + memory_ty.limits.maximum.map(|max| Pages(max)), + memory_ty.shared, + ) + .map_err(|x| LoadError::Codegen(format!("{:?}", x)))?; info.write().unwrap().memories.push(mem_desc); } diff --git a/lib/runtime-core/src/types.rs b/lib/runtime-core/src/types.rs index ab7c023a84b..bea89ffe39d 100644 --- a/lib/runtime-core/src/types.rs +++ b/lib/runtime-core/src/types.rs @@ -326,7 +326,7 @@ pub struct GlobalInit { pub init: Initializer, } -/// A wasm memory. +/// A wasm memory descriptor. #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] pub struct MemoryDescriptor { /// The minimum number of allowed pages. @@ -335,16 +335,30 @@ pub struct MemoryDescriptor { pub maximum: Option, /// This memory can be shared between wasm threads. pub shared: bool, + /// The type of the memory + pub memory_type: MemoryType, } impl MemoryDescriptor { - pub fn memory_type(self) -> MemoryType { - match (self.maximum.is_some(), self.shared) { + pub fn new(minimum: Pages, maximum: Option, shared: bool) -> Result { + let memory_type = match (maximum.is_some(), shared) { (true, true) => MemoryType::SharedStatic, (true, false) => MemoryType::Static, (false, false) => MemoryType::Dynamic, - (false, true) => panic!("shared memory without a max is not allowed"), - } + (false, true) => { + return Err("Max number of pages is required for shared memory".to_string()); + } + }; + Ok(MemoryDescriptor { + minimum, + maximum, + shared, + memory_type, + }) + } + + pub fn memory_type(&self) -> MemoryType { + self.memory_type } pub(crate) fn fits_in_imported(&self, imported: MemoryDescriptor) -> bool { From 374f81972a131fc41bcf1ccc1b94bdc9573971e6 Mon Sep 17 00:00:00 2001 From: Patrick Ventuzelo Date: Tue, 17 Sep 2019 17:46:36 +0200 Subject: [PATCH 07/49] remove panic from UnsharedMemory --- lib/runtime-core/src/memory/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/runtime-core/src/memory/mod.rs b/lib/runtime-core/src/memory/mod.rs index 6f6af5c65b4..bc82d2f822c 100644 --- a/lib/runtime-core/src/memory/mod.rs +++ b/lib/runtime-core/src/memory/mod.rs @@ -231,7 +231,11 @@ impl UnsharedMemory { MemoryType::Static => { UnsharedMemoryStorage::Static(StaticMemory::new(desc, &mut local)?) } - MemoryType::SharedStatic => panic!("attempting to create shared unshared memory"), + MemoryType::SharedStatic => { + return Err(CreationError::InvalidDescriptor( + "attempting to create shared unshared memory".to_string(), + )); + } }; Ok(Self { From 17a0e78cef5e3ef043f431784968fd78935047e8 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Tue, 17 Sep 2019 10:37:37 -0700 Subject: [PATCH 08/49] Implement Send for Instance --- lib/runtime-core/src/backing.rs | 20 ++++----- lib/runtime-core/src/export.rs | 4 ++ lib/runtime-core/src/global.rs | 8 ++-- lib/runtime-core/src/import.rs | 71 +++++++++++++++++++++++------- lib/runtime-core/src/typed_func.rs | 2 + 5 files changed, 72 insertions(+), 33 deletions(-) diff --git a/lib/runtime-core/src/backing.rs b/lib/runtime-core/src/backing.rs index 814dc56e79c..1bb3bec4dd8 100644 --- a/lib/runtime-core/src/backing.rs +++ b/lib/runtime-core/src/backing.rs @@ -536,9 +536,8 @@ fn import_functions( let namespace = module.info.namespace_table.get(*namespace_index); let name = module.info.name_table.get(*name_index); - let import = imports - .get_namespace(namespace) - .and_then(|namespace| namespace.get_export(name)); + let import = + imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name)); match import { Some(Export::Function { func, @@ -624,9 +623,8 @@ fn import_memories( let namespace = module.info.namespace_table.get(*namespace_index); let name = module.info.name_table.get(*name_index); - let memory_import = imports - .get_namespace(&namespace) - .and_then(|namespace| namespace.get_export(&name)); + let memory_import = + imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name)); match memory_import { Some(Export::Memory(memory)) => { if expected_memory_desc.fits_in_imported(memory.descriptor()) { @@ -696,9 +694,8 @@ fn import_tables( let namespace = module.info.namespace_table.get(*namespace_index); let name = module.info.name_table.get(*name_index); - let table_import = imports - .get_namespace(&namespace) - .and_then(|namespace| namespace.get_export(&name)); + let table_import = + imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name)); match table_import { Some(Export::Table(mut table)) => { if expected_table_desc.fits_in_imported(table.descriptor()) { @@ -767,9 +764,8 @@ fn import_globals( { let namespace = module.info.namespace_table.get(*namespace_index); let name = module.info.name_table.get(*name_index); - let import = imports - .get_namespace(namespace) - .and_then(|namespace| namespace.get_export(name)); + let import = + imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name)); match import { Some(Export::Global(mut global)) => { if global.descriptor() == *imported_global_desc { diff --git a/lib/runtime-core/src/export.rs b/lib/runtime-core/src/export.rs index 52ea9cf618e..96560cb6a0e 100644 --- a/lib/runtime-core/src/export.rs +++ b/lib/runtime-core/src/export.rs @@ -11,6 +11,8 @@ pub enum Context { Internal, } +unsafe impl Send for Context {} + #[derive(Debug, Clone)] pub enum Export { Function { @@ -26,6 +28,8 @@ pub enum Export { #[derive(Debug, Clone)] pub struct FuncPointer(*const vm::Func); +unsafe impl Send for FuncPointer {} + impl FuncPointer { /// This needs to be unsafe because there is /// no way to check whether the passed function diff --git a/lib/runtime-core/src/global.rs b/lib/runtime-core/src/global.rs index 8d421253112..beadd10ef4d 100644 --- a/lib/runtime-core/src/global.rs +++ b/lib/runtime-core/src/global.rs @@ -4,11 +4,11 @@ use crate::{ types::{GlobalDescriptor, Type, Value}, vm, }; -use std::{cell::RefCell, fmt, rc::Rc}; +use std::{cell::RefCell, fmt, sync::Arc}; pub struct Global { desc: GlobalDescriptor, - storage: Rc>, + storage: Arc>, } impl Global { @@ -56,7 +56,7 @@ impl Global { Self { desc, - storage: Rc::new(RefCell::new(local_global)), + storage: Arc::new(RefCell::new(local_global)), } } @@ -120,7 +120,7 @@ impl Clone for Global { fn clone(&self) -> Self { Self { desc: self.desc, - storage: Rc::clone(&self.storage), + storage: Arc::clone(&self.storage), } } } diff --git a/lib/runtime-core/src/import.rs b/lib/runtime-core/src/import.rs index fc1da43b730..c7e15c90d70 100644 --- a/lib/runtime-core/src/import.rs +++ b/lib/runtime-core/src/import.rs @@ -2,9 +2,9 @@ use crate::export::Export; use std::collections::VecDeque; use std::collections::{hash_map::Entry, HashMap}; use std::{ - cell::{Ref, RefCell}, + borrow::{Borrow, BorrowMut}, ffi::c_void, - rc::Rc, + sync::{Arc, Mutex}, }; pub trait LikeNamespace { @@ -45,8 +45,8 @@ impl IsExport for Export { /// } /// ``` pub struct ImportObject { - map: Rc>>>, - pub(crate) state_creator: Option (*mut c_void, fn(*mut c_void))>>, + map: Arc>>>, + pub(crate) state_creator: Option (*mut c_void, fn(*mut c_void)) + Send>>, pub allow_missing_functions: bool, } @@ -54,7 +54,7 @@ impl ImportObject { /// Create a new `ImportObject`. pub fn new() -> Self { Self { - map: Rc::new(RefCell::new(HashMap::new())), + map: Arc::new(Mutex::new(HashMap::new())), state_creator: None, allow_missing_functions: false, } @@ -62,11 +62,11 @@ impl ImportObject { pub fn new_with_data(state_creator: F) -> Self where - F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static, + F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static + Send, { Self { - map: Rc::new(RefCell::new(HashMap::new())), - state_creator: Some(Rc::new(state_creator)), + map: Arc::new(Mutex::new(HashMap::new())), + state_creator: Some(Arc::new(state_creator)), allow_missing_functions: false, } } @@ -92,9 +92,10 @@ impl ImportObject { pub fn register(&mut self, name: S, namespace: N) -> Option> where S: Into, - N: LikeNamespace + 'static, + N: LikeNamespace + Send + 'static, { - let mut map = self.map.borrow_mut(); + let mut guard = self.map.lock().unwrap(); + let map = guard.borrow_mut(); match map.entry(name.into()) { Entry::Vacant(empty) => { @@ -105,19 +106,50 @@ impl ImportObject { } } - pub fn get_namespace(&self, namespace: &str) -> Option> { - let map_ref = self.map.borrow(); - + /*pub fn get_namespace( + &self, + namespace: &str, + ) -> Option< + MutexGuardRef>, &(dyn LikeNamespace + Send)>, + > { + MutexGuardRef::new(self.map.lock().unwrap()) + .try_map(|mg| mg.get(namespace).map(|ns| &ns.as_ref()).ok_or(())) + .ok() + }*/ + + /// Apply a function on the namespace if it exists + /// If your function can fail, consider using `maybe_with_namespace` + pub fn with_namespace(&self, namespace: &str, f: Func) -> Option + where + Func: FnOnce(&(dyn LikeNamespace + Send)) -> InnerRet, + InnerRet: Sized, + { + let guard = self.map.lock().unwrap(); + let map_ref = guard.borrow(); if map_ref.contains_key(namespace) { - Some(Ref::map(map_ref, |map| &*map[namespace])) + Some(f(map_ref[namespace].as_ref())) } else { None } } + /// The same as `with_namespace` but takes a function that may fail + pub fn maybe_with_namespace(&self, namespace: &str, f: Func) -> Option + where + Func: FnOnce(&(dyn LikeNamespace + Send)) -> Option, + InnerRet: Sized, + { + let guard = self.map.lock().unwrap(); + let map_ref = guard.borrow(); + map_ref + .get(namespace) + .map(|ns| ns.as_ref()) + .and_then(|ns| f(ns)) + } + pub fn clone_ref(&self) -> Self { Self { - map: Rc::clone(&self.map), + map: Arc::clone(&self.map), state_creator: self.state_creator.clone(), allow_missing_functions: false, } @@ -125,7 +157,9 @@ impl ImportObject { fn get_objects(&self) -> VecDeque<(String, String, Export)> { let mut out = VecDeque::new(); - for (name, ns) in self.map.borrow().iter() { + let guard = self.map.lock().unwrap(); + let map = guard.borrow(); + for (name, ns) in map.iter() { for (id, exp) in ns.get_exports() { out.push_back((name.clone(), id, exp)); } @@ -158,7 +192,8 @@ impl IntoIterator for ImportObject { impl Extend<(String, String, Export)> for ImportObject { fn extend>(&mut self, iter: T) { - let mut map = self.map.borrow_mut(); + let mut guard = self.map.lock().unwrap(); + let map = guard.borrow_mut(); for (ns, id, exp) in iter.into_iter() { if let Some(like_ns) = map.get_mut(&ns) { like_ns.maybe_insert(&id, exp); @@ -175,6 +210,8 @@ pub struct Namespace { map: HashMap>, } +unsafe impl Send for Namespace {} + impl Namespace { pub fn new() -> Self { Self { diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index 91da26cbe37..789c858cb96 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -165,6 +165,8 @@ pub struct Func<'a, Args = (), Rets = (), Inner: Kind = Wasm> { _phantom: PhantomData<(&'a (), Args, Rets)>, } +unsafe impl<'a, Args, Rets> Send for Func<'a, Args, Rets> {} + impl<'a, Args, Rets> Func<'a, Args, Rets, Wasm> where Args: WasmTypeList, From 9e9343878d8ad9246218231623c2a7348daf61e2 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Tue, 17 Sep 2019 11:45:13 -0700 Subject: [PATCH 09/49] Implement Send for everything except Memory --- lib/runtime-core/src/export.rs | 2 ++ lib/runtime-core/src/global.rs | 19 +++++++++++++------ lib/runtime-core/src/import.rs | 8 +++----- lib/runtime-core/src/table/mod.rs | 26 +++++++++++++++++--------- lib/runtime-core/src/typed_func.rs | 3 ++- lib/runtime-core/src/vm.rs | 4 ++++ 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/lib/runtime-core/src/export.rs b/lib/runtime-core/src/export.rs index 96560cb6a0e..67cd1e5fff1 100644 --- a/lib/runtime-core/src/export.rs +++ b/lib/runtime-core/src/export.rs @@ -25,6 +25,8 @@ pub enum Export { Global(Global), } +unsafe impl Send for Export {} + #[derive(Debug, Clone)] pub struct FuncPointer(*const vm::Func); diff --git a/lib/runtime-core/src/global.rs b/lib/runtime-core/src/global.rs index beadd10ef4d..b59d1599b8e 100644 --- a/lib/runtime-core/src/global.rs +++ b/lib/runtime-core/src/global.rs @@ -4,11 +4,14 @@ use crate::{ types::{GlobalDescriptor, Type, Value}, vm, }; -use std::{cell::RefCell, fmt, sync::Arc}; +use std::{ + fmt, + sync::{Arc, Mutex}, +}; pub struct Global { desc: GlobalDescriptor, - storage: Arc>, + storage: Arc>, } impl Global { @@ -56,7 +59,7 @@ impl Global { Self { desc, - storage: Arc::new(RefCell::new(local_global)), + storage: Arc::new(Mutex::new(local_global)), } } @@ -83,7 +86,8 @@ impl Global { Value::V128(x) => x, }, }; - *self.storage.borrow_mut() = local_global; + let mut storage = self.storage.lock().unwrap(); + *storage = local_global; } else { panic!("Wrong type for setting this global") } @@ -94,7 +98,8 @@ impl Global { /// Get the value held by this global. pub fn get(&self) -> Value { - let data = self.storage.borrow().data; + let storage = self.storage.lock().unwrap(); + let data = storage.data; match self.desc.ty { Type::I32 => Value::I32(data as i32), @@ -105,8 +110,10 @@ impl Global { } } + // TODO: think about this and if this should now be unsafe pub(crate) fn vm_local_global(&mut self) -> *mut vm::LocalGlobal { - &mut *self.storage.borrow_mut() + let mut storage = self.storage.lock().unwrap(); + &mut *storage } } diff --git a/lib/runtime-core/src/import.rs b/lib/runtime-core/src/import.rs index c7e15c90d70..1b79e7422ae 100644 --- a/lib/runtime-core/src/import.rs +++ b/lib/runtime-core/src/import.rs @@ -207,11 +207,9 @@ impl Extend<(String, String, Export)> for ImportObject { } pub struct Namespace { - map: HashMap>, + map: HashMap>, } -unsafe impl Send for Namespace {} - impl Namespace { pub fn new() -> Self { Self { @@ -219,10 +217,10 @@ impl Namespace { } } - pub fn insert(&mut self, name: S, export: E) -> Option> + pub fn insert(&mut self, name: S, export: E) -> Option> where S: Into, - E: IsExport + 'static, + E: IsExport + Send + 'static, { self.map.insert(name.into(), Box::new(export)) } diff --git a/lib/runtime-core/src/table/mod.rs b/lib/runtime-core/src/table/mod.rs index 2e11507b1de..c83e72ae7cc 100644 --- a/lib/runtime-core/src/table/mod.rs +++ b/lib/runtime-core/src/table/mod.rs @@ -5,7 +5,10 @@ use crate::{ types::{ElementType, TableDescriptor}, vm, }; -use std::{cell::RefCell, fmt, ptr, rc::Rc}; +use std::{ + fmt, ptr, + sync::{Arc, Mutex}, +}; mod anyfunc; @@ -25,7 +28,7 @@ pub enum TableStorage { pub struct Table { desc: TableDescriptor, - storage: Rc>, + storage: Arc>, } impl Table { @@ -71,7 +74,7 @@ impl Table { Ok(Self { desc, - storage: Rc::new(RefCell::new((storage, local))), + storage: Arc::new(Mutex::new((storage, local))), }) } @@ -82,7 +85,8 @@ impl Table { /// Set the element at index. pub fn set(&self, index: u32, element: Element) -> Result<(), ()> { - match &mut *self.storage.borrow_mut() { + let mut storage = self.storage.lock().unwrap(); + match &mut *storage { (TableStorage::Anyfunc(ref mut anyfunc_table), _) => { match element { Element::Anyfunc(anyfunc) => anyfunc_table.set(index, anyfunc), @@ -96,14 +100,16 @@ impl Table { where F: FnOnce(&mut [vm::Anyfunc]) -> R, { - match &mut *self.storage.borrow_mut() { + let mut storage = self.storage.lock().unwrap(); + match &mut *storage { (TableStorage::Anyfunc(ref mut anyfunc_table), _) => f(anyfunc_table.internal_buffer()), } } /// The current size of this table. pub fn size(&self) -> u32 { - match &*self.storage.borrow() { + let storage = self.storage.lock().unwrap(); + match &*storage { (TableStorage::Anyfunc(ref anyfunc_table), _) => anyfunc_table.current_size(), } } @@ -114,7 +120,8 @@ impl Table { return Ok(self.size()); } - match &mut *self.storage.borrow_mut() { + let mut storage = self.storage.lock().unwrap(); + match &mut *storage { (TableStorage::Anyfunc(ref mut anyfunc_table), ref mut local) => anyfunc_table .grow(delta, local) .ok_or(GrowError::TableGrowError), @@ -122,7 +129,8 @@ impl Table { } pub fn vm_local_table(&mut self) -> *mut vm::LocalTable { - &mut self.storage.borrow_mut().1 + let mut storage = self.storage.lock().unwrap(); + &mut storage.1 } } @@ -136,7 +144,7 @@ impl Clone for Table { fn clone(&self) -> Self { Self { desc: self.desc, - storage: Rc::clone(&self.storage), + storage: Arc::clone(&self.storage), } } } diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index 789c858cb96..0014e13cd7d 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -165,7 +165,8 @@ pub struct Func<'a, Args = (), Rets = (), Inner: Kind = Wasm> { _phantom: PhantomData<(&'a (), Args, Rets)>, } -unsafe impl<'a, Args, Rets> Send for Func<'a, Args, Rets> {} +unsafe impl<'a, Args, Rets> Send for Func<'a, Args, Rets, Wasm> {} +unsafe impl<'a, Args, Rets> Send for Func<'a, Args, Rets, Host> {} impl<'a, Args, Rets> Func<'a, Args, Rets, Wasm> where diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 51f883318d1..1b85ecedcfa 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -501,6 +501,8 @@ pub struct LocalTable { pub table: *mut (), } +unsafe impl Send for LocalTable {} + impl LocalTable { #[allow(clippy::erasing_op)] // TODO pub fn offset_base() -> u8 { @@ -580,6 +582,8 @@ pub struct Anyfunc { pub sig_id: SigId, } +unsafe impl Send for Anyfunc {} + impl Anyfunc { pub fn null() -> Self { Self { From 83c3909b00df2d7d0dfb55d6d641fe63308f05d7 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Tue, 17 Sep 2019 14:58:26 -0700 Subject: [PATCH 10/49] Implement it for memory and make Instance Send --- lib/runtime-core/src/backing.rs | 4 +++ lib/runtime-core/src/export.rs | 2 -- lib/runtime-core/src/import.rs | 5 ++-- lib/runtime-core/src/instance.rs | 2 ++ lib/runtime-core/src/memory/mod.rs | 40 ++++++++++++++----------- lib/runtime-core/src/sys/unix/memory.rs | 6 ++-- lib/runtime-core/src/vm.rs | 2 ++ 7 files changed, 37 insertions(+), 24 deletions(-) diff --git a/lib/runtime-core/src/backing.rs b/lib/runtime-core/src/backing.rs index 1bb3bec4dd8..df1ab0e9626 100644 --- a/lib/runtime-core/src/backing.rs +++ b/lib/runtime-core/src/backing.rs @@ -54,6 +54,8 @@ pub struct LocalBacking { pub(crate) internals: Internals, } +unsafe impl Send for LocalBacking {} + impl LocalBacking { pub(crate) fn new( module: &ModuleInner, @@ -461,6 +463,8 @@ pub struct ImportBacking { pub(crate) vm_globals: BoxedMap, } +unsafe impl Send for ImportBacking {} + impl ImportBacking { pub fn new( module: &ModuleInner, diff --git a/lib/runtime-core/src/export.rs b/lib/runtime-core/src/export.rs index 67cd1e5fff1..96560cb6a0e 100644 --- a/lib/runtime-core/src/export.rs +++ b/lib/runtime-core/src/export.rs @@ -25,8 +25,6 @@ pub enum Export { Global(Global), } -unsafe impl Send for Export {} - #[derive(Debug, Clone)] pub struct FuncPointer(*const vm::Func); diff --git a/lib/runtime-core/src/import.rs b/lib/runtime-core/src/import.rs index 1b79e7422ae..c66cc28f996 100644 --- a/lib/runtime-core/src/import.rs +++ b/lib/runtime-core/src/import.rs @@ -46,7 +46,8 @@ impl IsExport for Export { /// ``` pub struct ImportObject { map: Arc>>>, - pub(crate) state_creator: Option (*mut c_void, fn(*mut c_void)) + Send>>, + pub(crate) state_creator: + Option (*mut c_void, fn(*mut c_void)) + Send + Sync + 'static>>, pub allow_missing_functions: bool, } @@ -62,7 +63,7 @@ impl ImportObject { pub fn new_with_data(state_creator: F) -> Self where - F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static + Send, + F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static + Send + Sync, { Self { map: Arc::new(Mutex::new(HashMap::new())), diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index e6ba365f6ef..50ab0ce0088 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -25,6 +25,8 @@ pub(crate) struct InstanceInner { pub(crate) vmctx: *mut vm::Ctx, } +unsafe impl Send for InstanceInner {} + impl Drop for InstanceInner { fn drop(&mut self) { // Drop the vmctx. diff --git a/lib/runtime-core/src/memory/mod.rs b/lib/runtime-core/src/memory/mod.rs index 75e9ea007dc..ee71160adab 100644 --- a/lib/runtime-core/src/memory/mod.rs +++ b/lib/runtime-core/src/memory/mod.rs @@ -8,12 +8,9 @@ use crate::{ units::Pages, vm, }; -use std::{ - cell::{Cell, RefCell}, - fmt, mem, - rc::Rc, - sync::Arc, -}; +use std::{cell::Cell, fmt, mem, sync::Arc}; + +use std::sync::Mutex as StdMutex; pub use self::dynamic::DynamicMemory; pub use self::static_::StaticMemory; @@ -208,14 +205,17 @@ enum UnsharedMemoryStorage { } pub struct UnsharedMemory { - internal: Rc, + internal: Arc, } struct UnsharedMemoryInternal { - storage: RefCell, + storage: StdMutex, local: Cell, } +unsafe impl Send for UnsharedMemoryInternal {} +unsafe impl Sync for UnsharedMemoryInternal {} + impl UnsharedMemory { pub fn new(desc: MemoryDescriptor) -> Result { let mut local = vm::LocalMemory { @@ -235,15 +235,15 @@ impl UnsharedMemory { }; Ok(Self { - internal: Rc::new(UnsharedMemoryInternal { - storage: RefCell::new(storage), + internal: Arc::new(UnsharedMemoryInternal { + storage: StdMutex::new(storage), local: Cell::new(local), }), }) } pub fn grow(&self, delta: Pages) -> Result { - let mut storage = self.internal.storage.borrow_mut(); + let mut storage = self.internal.storage.lock().unwrap(); let mut local = self.internal.local.get(); @@ -260,7 +260,7 @@ impl UnsharedMemory { } pub fn size(&self) -> Pages { - let storage = self.internal.storage.borrow(); + let storage = self.internal.storage.lock().unwrap(); match &*storage { UnsharedMemoryStorage::Dynamic(ref dynamic_memory) => dynamic_memory.size(), @@ -276,7 +276,7 @@ impl UnsharedMemory { impl Clone for UnsharedMemory { fn clone(&self) -> Self { UnsharedMemory { - internal: Rc::clone(&self.internal), + internal: Arc::clone(&self.internal), } } } @@ -286,11 +286,14 @@ pub struct SharedMemory { } pub struct SharedMemoryInternal { - memory: RefCell>, + memory: StdMutex>, local: Cell, lock: Mutex<()>, } +unsafe impl Send for SharedMemoryInternal {} +unsafe impl Sync for SharedMemoryInternal {} + impl SharedMemory { fn new(desc: MemoryDescriptor) -> Result { let mut local = vm::LocalMemory { @@ -303,7 +306,7 @@ impl SharedMemory { Ok(Self { internal: Arc::new(SharedMemoryInternal { - memory: RefCell::new(memory), + memory: StdMutex::new(memory), local: Cell::new(local), lock: Mutex::new(()), }), @@ -313,15 +316,18 @@ impl SharedMemory { pub fn grow(&self, delta: Pages) -> Result { let _guard = self.internal.lock.lock(); let mut local = self.internal.local.get(); - let pages = self.internal.memory.borrow_mut().grow(delta, &mut local); + let mut memory = self.internal.memory.lock().unwrap(); + let pages = memory.grow(delta, &mut local); pages } pub fn size(&self) -> Pages { let _guard = self.internal.lock.lock(); - self.internal.memory.borrow_mut().size() + let memory = self.internal.memory.lock().unwrap(); + memory.size() } + // This function is scary, because the mutex is not locked here pub(crate) fn vm_local_memory(&self) -> *mut vm::LocalMemory { self.internal.local.as_ptr() } diff --git a/lib/runtime-core/src/sys/unix/memory.rs b/lib/runtime-core/src/sys/unix/memory.rs index f4af2493b61..fc60d732b6f 100644 --- a/lib/runtime-core/src/sys/unix/memory.rs +++ b/lib/runtime-core/src/sys/unix/memory.rs @@ -4,7 +4,7 @@ use errno; use nix::libc; use page_size; use std::ops::{Bound, RangeBounds}; -use std::{fs::File, os::unix::io::IntoRawFd, path::Path, ptr, rc::Rc, slice}; +use std::{fs::File, os::unix::io::IntoRawFd, path::Path, ptr, slice, sync::Arc}; unsafe impl Send for Memory {} unsafe impl Sync for Memory {} @@ -14,7 +14,7 @@ pub struct Memory { ptr: *mut u8, size: usize, protection: Protect, - fd: Option>, + fd: Option>, } impl Memory { @@ -49,7 +49,7 @@ impl Memory { ptr: ptr as *mut u8, size: file_len as usize, protection, - fd: Some(Rc::new(raw_fd)), + fd: Some(Arc::new(raw_fd)), }) } } diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 1b85ecedcfa..5f1f1fb0cef 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -474,6 +474,8 @@ pub struct ImportedFunc { pub vmctx: *mut Ctx, } +unsafe impl Send for ImportedFunc {} + impl ImportedFunc { #[allow(clippy::erasing_op)] // TODO pub fn offset_func() -> u8 { From 71b865aa1144dd181a61821ebb5b196f8cc8d8df Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2019 22:16:38 +0000 Subject: [PATCH 11/49] Bump rand from 0.7.0 to 0.7.2 Bumps [rand](https://github.com/rust-random/rand) from 0.7.0 to 0.7.2. - [Release notes](https://github.com/rust-random/rand/releases) - [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-random/rand/compare/0.7.0...0.7.2) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11c8633e316..b26948e6846 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -961,7 +961,7 @@ dependencies = [ [[package]] name = "rand" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1333,7 +1333,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1590,7 +1590,7 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.7.0", ] @@ -1749,7 +1749,7 @@ dependencies = [ "generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1964,7 +1964,7 @@ dependencies = [ "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" +"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" From 9c205e05a2cd7818d07b2279613972aec7e08ac6 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Tue, 17 Sep 2019 18:35:12 -0700 Subject: [PATCH 12/49] Add comments explaining the unsafe impls and simplify the code, too --- lib/runtime-core/src/backing.rs | 2 ++ lib/runtime-core/src/export.rs | 2 ++ lib/runtime-core/src/import.rs | 11 ----------- lib/runtime-core/src/instance.rs | 1 + lib/runtime-core/src/memory/mod.rs | 6 ++++-- lib/runtime-core/src/vm.rs | 6 ++++++ 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/runtime-core/src/backing.rs b/lib/runtime-core/src/backing.rs index df1ab0e9626..ef43bd58c64 100644 --- a/lib/runtime-core/src/backing.rs +++ b/lib/runtime-core/src/backing.rs @@ -54,6 +54,7 @@ pub struct LocalBacking { pub(crate) internals: Internals, } +// Manually implemented because LocalBacking contains raw pointers directly unsafe impl Send for LocalBacking {} impl LocalBacking { @@ -463,6 +464,7 @@ pub struct ImportBacking { pub(crate) vm_globals: BoxedMap, } +// manually implemented because ImportBacking contains raw pointers directly unsafe impl Send for ImportBacking {} impl ImportBacking { diff --git a/lib/runtime-core/src/export.rs b/lib/runtime-core/src/export.rs index 96560cb6a0e..7960d76e699 100644 --- a/lib/runtime-core/src/export.rs +++ b/lib/runtime-core/src/export.rs @@ -11,6 +11,7 @@ pub enum Context { Internal, } +// Manually implemented because context contains a raw pointer to Ctx unsafe impl Send for Context {} #[derive(Debug, Clone)] @@ -28,6 +29,7 @@ pub enum Export { #[derive(Debug, Clone)] pub struct FuncPointer(*const vm::Func); +// Manually implemented because FuncPointer contains a raw pointer to Ctx unsafe impl Send for FuncPointer {} impl FuncPointer { diff --git a/lib/runtime-core/src/import.rs b/lib/runtime-core/src/import.rs index c66cc28f996..ff09450feb1 100644 --- a/lib/runtime-core/src/import.rs +++ b/lib/runtime-core/src/import.rs @@ -107,17 +107,6 @@ impl ImportObject { } } - /*pub fn get_namespace( - &self, - namespace: &str, - ) -> Option< - MutexGuardRef>, &(dyn LikeNamespace + Send)>, - > { - MutexGuardRef::new(self.map.lock().unwrap()) - .try_map(|mg| mg.get(namespace).map(|ns| &ns.as_ref()).ok_or(())) - .ok() - }*/ - /// Apply a function on the namespace if it exists /// If your function can fail, consider using `maybe_with_namespace` pub fn with_namespace(&self, namespace: &str, f: Func) -> Option diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index 50ab0ce0088..6f30b0a7489 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -25,6 +25,7 @@ pub(crate) struct InstanceInner { pub(crate) vmctx: *mut vm::Ctx, } +// manually implemented because InstanceInner contains a raw pointer to Ctx unsafe impl Send for InstanceInner {} impl Drop for InstanceInner { diff --git a/lib/runtime-core/src/memory/mod.rs b/lib/runtime-core/src/memory/mod.rs index ee71160adab..7f272be37bb 100644 --- a/lib/runtime-core/src/memory/mod.rs +++ b/lib/runtime-core/src/memory/mod.rs @@ -213,7 +213,8 @@ struct UnsharedMemoryInternal { local: Cell, } -unsafe impl Send for UnsharedMemoryInternal {} +// Manually implemented because UnsharedMemoryInternal uses `Cell` and is used in an Arc; +// this is safe because the lock for storage can be used to protect (seems like a weak reason: PLEASE REVIEW!) unsafe impl Sync for UnsharedMemoryInternal {} impl UnsharedMemory { @@ -291,7 +292,8 @@ pub struct SharedMemoryInternal { lock: Mutex<()>, } -unsafe impl Send for SharedMemoryInternal {} +// Manually implemented because SharedMemoryInternal uses `Cell` and is used in Arc; +// this is safe because of `lock`; accesing `local` without locking `lock` is not safe (Maybe we could put the lock on Local then?) unsafe impl Sync for SharedMemoryInternal {} impl SharedMemory { diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 5f1f1fb0cef..40ca5d16ef1 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -474,6 +474,7 @@ pub struct ImportedFunc { pub vmctx: *mut Ctx, } +// manually implemented because ImportedFunc contains raw pointers directly; `Func` is marked Send (But `Ctx` actually isn't! (TODO: review this, shouldn't `Ctx` be Send?)) unsafe impl Send for ImportedFunc {} impl ImportedFunc { @@ -503,6 +504,7 @@ pub struct LocalTable { pub table: *mut (), } +// manually implemented because LocalTable contains raw pointers directly unsafe impl Send for LocalTable {} impl LocalTable { @@ -534,6 +536,9 @@ pub struct LocalMemory { pub memory: *mut (), } +// manually implemented because LocalMemory contains raw pointers +unsafe impl Send for LocalMemory {} + impl LocalMemory { #[allow(clippy::erasing_op)] // TODO pub fn offset_base() -> u8 { @@ -584,6 +589,7 @@ pub struct Anyfunc { pub sig_id: SigId, } +// manually implemented because Anyfunc contains raw pointers directly unsafe impl Send for Anyfunc {} impl Anyfunc { From e8a918e2e5f37e0d9d57d876eb036800b96ed56d Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 18 Sep 2019 23:25:35 +0200 Subject: [PATCH 13/49] %lld -> %ld fixes cargo test compile error --- lib/runtime-c-api/tests/test-exports.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/runtime-c-api/tests/test-exports.c b/lib/runtime-c-api/tests/test-exports.c index 3af813d0e5c..893174908a5 100644 --- a/lib/runtime-c-api/tests/test-exports.c +++ b/lib/runtime-c-api/tests/test-exports.c @@ -242,7 +242,7 @@ int main() wasmer_result_t call_result = wasmer_export_func_call(exported_function, inputs, inputs_arity, outputs, outputs_arity); - printf("Result: %lld\n", outputs[0].value.I64); + printf("Result: %ld\n", outputs[0].value.I64); assert(outputs[0].value.I64 == 7); assert(call_result == WASMER_OK); From 8ae255b51a6fd615393b6a72b9066e8861117cd8 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 19 Sep 2019 00:19:17 +0200 Subject: [PATCH 14/49] Fix issues with testing/linking singlepass in runtime-c-api --- lib/runtime-core/image-loading-linux-x86-64.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/runtime-core/image-loading-linux-x86-64.s b/lib/runtime-core/image-loading-linux-x86-64.s index 1d86bab0806..859f010f830 100644 --- a/lib/runtime-core/image-loading-linux-x86-64.s +++ b/lib/runtime-core/image-loading-linux-x86-64.s @@ -81,7 +81,7 @@ pushq %r8 pushq %r9 pushq %r10 -callq get_boundary_register_preservation +callq get_boundary_register_preservation@PLT # Keep this consistent with BoundaryRegisterPreservation movq %r15, 0(%rax) From 5741a2cf7004afa3e341c49294d374254495ada9 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Wed, 18 Sep 2019 16:06:46 -0700 Subject: [PATCH 15/49] Implement function lookups using the table --- lib/runtime-core/src/instance.rs | 56 +++++++++++++++++---------- lib/runtime-core/src/table/anyfunc.rs | 2 +- lib/runtime-core/src/table/mod.rs | 3 +- lib/runtime-core/src/vm.rs | 54 ++++++++++++++++---------- 4 files changed, 71 insertions(+), 44 deletions(-) diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index 97b2d362927..f1ce0a19376 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -518,7 +518,7 @@ impl LikeNamespace for Rc { } #[must_use] -pub(crate) fn call_func_with_index( +fn call_func_with_index( info: &ModuleInfo, runnable: &dyn RunnableModule, import_backing: &ImportBacking, @@ -527,29 +527,12 @@ pub(crate) fn call_func_with_index( args: &[Value], rets: &mut Vec, ) -> CallResult<()> { - rets.clear(); - let sig_index = *info .func_assoc .get(func_index) .expect("broken invariant, incorrect func index"); let signature = &info.signatures[sig_index]; - let num_results = signature.returns().len(); - let num_results = num_results - + signature - .returns() - .iter() - .filter(|&&ty| ty == Type::V128) - .count(); - rets.reserve(num_results); - - if !signature.check_param_value_types(args) { - Err(ResolveError::Signature { - expected: signature.clone(), - found: args.iter().map(|val| val.ty()).collect(), - })? - } let func_ptr = match func_index.local_or_import(info) { LocalOrImport::Local(local_func_index) => { @@ -567,6 +550,39 @@ pub(crate) fn call_func_with_index( } }; + let wasm = runnable + .get_trampoline(info, sig_index) + .expect("wasm trampoline"); + + call_func_with_index_inner(ctx_ptr, func_ptr, signature, wasm, args, rets) +} + +pub(crate) fn call_func_with_index_inner( + ctx_ptr: *mut vm::Ctx, + func_ptr: NonNull, + signature: &FuncSig, + wasm: Wasm, + args: &[Value], + rets: &mut Vec, +) -> CallResult<()> { + rets.clear(); + + let num_results = signature.returns().len(); + let num_results = num_results + + signature + .returns() + .iter() + .filter(|&&ty| ty == Type::V128) + .count(); + rets.reserve(num_results); + + if !signature.check_param_value_types(args) { + Err(ResolveError::Signature { + expected: signature.clone(), + found: args.iter().map(|val| val.ty()).collect(), + })? + } + let mut raw_args: SmallVec<[u64; 8]> = SmallVec::new(); for v in args { match v { @@ -598,9 +614,7 @@ pub(crate) fn call_func_with_index( trampoline, invoke, invoke_env, - } = runnable - .get_trampoline(info, sig_index) - .expect("wasm trampoline"); + } = wasm; let run_wasm = |result_space: *mut u64| unsafe { let mut trap_info = WasmTrapInfo::Unknown; diff --git a/lib/runtime-core/src/table/anyfunc.rs b/lib/runtime-core/src/table/anyfunc.rs index 789f67ada2b..8336b502882 100644 --- a/lib/runtime-core/src/table/anyfunc.rs +++ b/lib/runtime-core/src/table/anyfunc.rs @@ -44,7 +44,7 @@ impl<'a> From> for Anyfunc<'a> { } pub struct AnyfuncTable { - backing: Vec, + pub backing: Vec, max: Option, } diff --git a/lib/runtime-core/src/table/mod.rs b/lib/runtime-core/src/table/mod.rs index 2e11507b1de..8fb32150157 100644 --- a/lib/runtime-core/src/table/mod.rs +++ b/lib/runtime-core/src/table/mod.rs @@ -9,8 +9,7 @@ use std::{cell::RefCell, fmt, ptr, rc::Rc}; mod anyfunc; -pub use self::anyfunc::Anyfunc; -use self::anyfunc::AnyfuncTable; +pub use self::anyfunc::{Anyfunc, AnyfuncTable}; use crate::error::GrowError; pub enum Element<'a> { diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 7c811e36ecf..a4abc7b0298 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -1,17 +1,19 @@ pub use crate::backing::{ImportBacking, LocalBacking, INTERNALS_SIZE}; use crate::{ - error::{CallError, CallResult, RuntimeError}, - instance::call_func_with_index, + error::CallResult, + instance::call_func_with_index_inner, memory::{Memory, MemoryType}, module::{ModuleInfo, ModuleInner}, + sig_registry::SigRegistry, structures::TypedIndex, - types::{FuncIndex, LocalOrImport, MemoryIndex, Value}, + types::{LocalOrImport, MemoryIndex, TableIndex, Value}, vmcalls, }; use std::{ cell::UnsafeCell, ffi::c_void, - mem, ptr, + mem, + ptr::{self, NonNull}, sync::atomic::{AtomicUsize, Ordering}, sync::Once, }; @@ -397,24 +399,36 @@ impl Ctx { } /// Calls a host or Wasm function at the given index - pub fn call_with_index(&mut self, index: FuncIndex, args: &[Value]) -> CallResult> { - let module = unsafe { &(*self.module) }; - if module.info.func_assoc.get(index).is_none() { - return Err(CallError::Runtime(RuntimeError::Trap { - msg: format!("Index out of bounds: {}", index.index()).into_boxed_str(), - })); - } - let mut output = vec![]; - call_func_with_index( - &module.info, - module.runnable_module.as_ref(), - unsafe { &*self.import_backing }, - self as *mut Ctx, - index, + pub fn call_with_index(&mut self, index: TableIndex, args: &[Value]) -> CallResult> { + let anyfunc_table = + unsafe { &*((**self.internal.tables).table as *mut crate::table::AnyfuncTable) }; + let entry = anyfunc_table.backing[index.index()]; + + let fn_ptr = entry.func; + let sig_id = entry.sig_id; + let signature = SigRegistry.lookup_signature(unsafe { std::mem::transmute(sig_id.0) }); + let mut rets = vec![]; + + let wasm = { + let module = unsafe { &*self.module }; + let runnable = &module.runnable_module; + + let sig_index = SigRegistry.lookup_sig_index(signature.clone()); + runnable + .get_trampoline(&module.info, sig_index) + .expect("wasm trampoline") + }; + + call_func_with_index_inner( + self as *mut Ctx, /* doesn't handle all cases */ + NonNull::new(fn_ptr as *mut _).unwrap(), + &signature, + wasm, args, - &mut output, + &mut rets, )?; - Ok(output) + + Ok(rets) } } From ccd369ff0c4b2510babee32caf81a281c1b3c9c7 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Wed, 18 Sep 2019 16:43:47 -0700 Subject: [PATCH 16/49] Add example, rename Ctx fn, make things pub(crate), misc changes --- .github/pull_request_template.md | 2 +- CHANGELOG.md | 2 ++ Cargo.toml | 6 +++- examples/callback-guest.rs | 24 ++++++++++++++ examples/callback-guest.wasm | Bin 0 -> 31667 bytes examples/callback.rs | 46 ++++++++++++++++++++++++++ lib/runtime-core/src/table/anyfunc.rs | 2 +- lib/runtime-core/src/table/mod.rs | 3 +- lib/runtime-core/src/vm.rs | 16 +++++---- 9 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 examples/callback-guest.rs create mode 100755 examples/callback-guest.wasm create mode 100644 examples/callback.rs diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 609e0c83f7c..b29669d33b3 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -12,4 +12,4 @@ links to related issues, and the context of the PR. # Review -- [ ] Create a short description of the the change in the CHANGELOG.md file +- [ ] Add a short description of the the change to the CHANGELOG.md file diff --git a/CHANGELOG.md b/CHANGELOG.md index 4672f8d701b..ed517016d93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ Blocks of changes will separated by version increments. ## **[Unreleased]** +- [#803](https://github.com/wasmerio/wasmer/issues/803) Add method to `Ctx` to invoke functions by their `TableIndex` + ## 0.7.0 - 2019-09-12 Special thanks to @YaronWittenstein @penberg for their contributions. diff --git a/Cargo.toml b/Cargo.toml index 31ba526bd0b..06b2c2854dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,7 +58,7 @@ members = [ "lib/wasi-tests", "lib/emscripten-tests", "lib/middleware-common-tests", - "examples/plugin-for-example" + "examples/plugin-for-example", ] [build-dependencies] @@ -105,3 +105,7 @@ managed = ["backend-singlepass", "wasmer-runtime-core/managed"] [[example]] name = "plugin" crate-type = ["bin"] + +[[example]] +name = "callback" +crate-type = ["bin"] diff --git a/examples/callback-guest.rs b/examples/callback-guest.rs new file mode 100644 index 00000000000..129ad05c8ac --- /dev/null +++ b/examples/callback-guest.rs @@ -0,0 +1,24 @@ +extern "C" { + fn call_guest_fn(f: u32) -> u32; + fn call_guest_fn2(f: u32) -> u32; + fn host_callback() -> u32; +} + +#[no_mangle] +fn test_callback() -> u32 { + 42 +} + +#[no_mangle] +fn test_callback2() -> u32 { + 45 +} + +fn main() { + unsafe { call_guest_fn(test_callback as usize as u32) }; + unsafe { call_guest_fn(host_callback as usize as u32) }; + unsafe { call_guest_fn(test_callback2 as usize as u32) }; + unsafe { call_guest_fn2(test_callback2 as usize as u32) }; + unsafe { call_guest_fn2(test_callback as usize as u32) }; + unsafe { call_guest_fn2(host_callback as usize as u32) }; +} diff --git a/examples/callback-guest.wasm b/examples/callback-guest.wasm new file mode 100755 index 0000000000000000000000000000000000000000..05558297595555751c3b484fce3f763f1828c182 GIT binary patch literal 31667 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 literal 0 HcmV?d00001 diff --git a/examples/callback.rs b/examples/callback.rs new file mode 100644 index 00000000000..732a6a1a43f --- /dev/null +++ b/examples/callback.rs @@ -0,0 +1,46 @@ +/// This example demonstrates the use of callbacks: calling functions (Host and Wasm) +/// passed to us from the Wasm via hostcall +use wasmer_runtime::{compile_with, compiler_for_backend, func, imports, Backend, Ctx}; +use wasmer_runtime_core::{structures::TypedIndex, types::TableIndex}; + +static WASM: &'static str = "examples/callback-guest.wasm"; + +/// This function matches our arbitrarily decided callback signature +/// in this example we'll only call functions that take no arguments and return one value +fn host_callback(_ctx: &mut Ctx) -> u32 { + 55 +} + +fn call_guest_fn(ctx: &mut Ctx, guest_fn: u32) -> u32 { + // We get a TableIndex from our raw value passed in + let guest_fn_typed = TableIndex::new(guest_fn as usize); + // and use it to call the corresponding function + let result = ctx.call_with_table_index(guest_fn_typed, &[]).unwrap(); + + println!("Guest fn {} returned {:?}", guest_fn, result); + + 0 +} + +fn main() { + let wasm_bytes = + std::fs::read(WASM).expect(&format!("Could not read in WASM plugin at {}", WASM)); + + let imports = imports! { + "env" => { + "call_guest_fn" => func!(call_guest_fn), + "call_guest_fn2" => func!(call_guest_fn), + "host_callback" => func!(host_callback), + }, + }; + + let compiler = compiler_for_backend(Backend::default()).unwrap(); + let module = compile_with(&wasm_bytes[..], compiler.as_ref()).unwrap(); + let instance = module + .instantiate(&imports) + .expect("failed to instantiate wasm module"); + + let entry_point = instance.func::<(u32, u32), u32>("main").unwrap(); + + entry_point.call(0, 0).expect("START"); +} diff --git a/lib/runtime-core/src/table/anyfunc.rs b/lib/runtime-core/src/table/anyfunc.rs index 8336b502882..4a63c8f6249 100644 --- a/lib/runtime-core/src/table/anyfunc.rs +++ b/lib/runtime-core/src/table/anyfunc.rs @@ -44,7 +44,7 @@ impl<'a> From> for Anyfunc<'a> { } pub struct AnyfuncTable { - pub backing: Vec, + pub(crate) backing: Vec, max: Option, } diff --git a/lib/runtime-core/src/table/mod.rs b/lib/runtime-core/src/table/mod.rs index 8fb32150157..1b61cd75438 100644 --- a/lib/runtime-core/src/table/mod.rs +++ b/lib/runtime-core/src/table/mod.rs @@ -9,7 +9,8 @@ use std::{cell::RefCell, fmt, ptr, rc::Rc}; mod anyfunc; -pub use self::anyfunc::{Anyfunc, AnyfuncTable}; +pub use self::anyfunc::Anyfunc; +pub(crate) use self::anyfunc::AnyfuncTable; use crate::error::GrowError; pub enum Element<'a> { diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index a4abc7b0298..e3084a9c5fa 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -398,14 +398,16 @@ impl Ctx { } } - /// Calls a host or Wasm function at the given index - pub fn call_with_index(&mut self, index: TableIndex, args: &[Value]) -> CallResult> { + /// Calls a host or Wasm function at the given table index + pub fn call_with_table_index( + &mut self, + index: TableIndex, + args: &[Value], + ) -> CallResult> { let anyfunc_table = unsafe { &*((**self.internal.tables).table as *mut crate::table::AnyfuncTable) }; - let entry = anyfunc_table.backing[index.index()]; + let Anyfunc { func, ctx, sig_id } = anyfunc_table.backing[index.index()]; - let fn_ptr = entry.func; - let sig_id = entry.sig_id; let signature = SigRegistry.lookup_signature(unsafe { std::mem::transmute(sig_id.0) }); let mut rets = vec![]; @@ -420,8 +422,8 @@ impl Ctx { }; call_func_with_index_inner( - self as *mut Ctx, /* doesn't handle all cases */ - NonNull::new(fn_ptr as *mut _).unwrap(), + ctx, + NonNull::new(func as *mut _).unwrap(), &signature, wasm, args, From a090bec49081bae2b79d9ce8926333d90153def7 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Wed, 18 Sep 2019 17:12:48 -0700 Subject: [PATCH 17/49] Add examples step in Makefile and add it to integration-tests --- Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 007e89853b0..5eb9c9aa23e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: spectests emtests clean build install lint precommit docs +.PHONY: spectests emtests clean build install lint precommit docs examples # Generate files generate-spectests: @@ -111,12 +111,16 @@ test: spectests emtests middleware wasitests circleci-clean test-rest # Integration tests -integration-tests: release-clif +integration-tests: release-clif examples echo "Running Integration Tests" ./integration_tests/lua/test.sh ./integration_tests/nginx/test.sh ./integration_tests/cowsay/test.sh +examples: + cargo run --example plugin + cargo run --example callback + # Utils lint: From 451b458fc36531edf32bb66ad66fb1531d9bab55 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Thu, 19 Sep 2019 10:39:47 -0700 Subject: [PATCH 18/49] Add feature matrix document --- docs/feature_matrix.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 docs/feature_matrix.md diff --git a/docs/feature_matrix.md b/docs/feature_matrix.md new file mode 100644 index 00000000000..51808065b09 --- /dev/null +++ b/docs/feature_matrix.md @@ -0,0 +1,20 @@ +# Feature Table + +## Compiler Backend + +|   | Singlepass | Cranelift | LLVM | +| - | - | - | - | +| Caching | No | Yes | Yes | +| SIMD | No | No | Yes | +| Multi-value return | No | No | No | + + +## Language integration + +TODO: define a set of features that are relevant and mark them here + +Current ideas: + +- WASI FS API +- Callbacks? (not even in Rust yet) +- Exiting early in hostcall From 3b200fa4d3e1f798583c7cdf8f0e81b24d02f686 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Thu, 19 Sep 2019 13:53:07 -0700 Subject: [PATCH 19/49] Move callback guest out of direct examples dir --- examples/callback-guest/README.md | 5 +++++ examples/{ => callback-guest}/callback-guest.rs | 0 examples/{ => callback-guest}/callback-guest.wasm | Bin examples/callback.rs | 2 +- 4 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 examples/callback-guest/README.md rename examples/{ => callback-guest}/callback-guest.rs (100%) rename examples/{ => callback-guest}/callback-guest.wasm (100%) diff --git a/examples/callback-guest/README.md b/examples/callback-guest/README.md new file mode 100644 index 00000000000..6439ef00dd4 --- /dev/null +++ b/examples/callback-guest/README.md @@ -0,0 +1,5 @@ +# Call back guest + +This is part of the `callback` example. This Wasm module passes host imports and its own functions to the Wasm host to execute. + +See `examples/callback.rs` for the host diff --git a/examples/callback-guest.rs b/examples/callback-guest/callback-guest.rs similarity index 100% rename from examples/callback-guest.rs rename to examples/callback-guest/callback-guest.rs diff --git a/examples/callback-guest.wasm b/examples/callback-guest/callback-guest.wasm similarity index 100% rename from examples/callback-guest.wasm rename to examples/callback-guest/callback-guest.wasm diff --git a/examples/callback.rs b/examples/callback.rs index 732a6a1a43f..e5969fec971 100644 --- a/examples/callback.rs +++ b/examples/callback.rs @@ -3,7 +3,7 @@ use wasmer_runtime::{compile_with, compiler_for_backend, func, imports, Backend, Ctx}; use wasmer_runtime_core::{structures::TypedIndex, types::TableIndex}; -static WASM: &'static str = "examples/callback-guest.wasm"; +static WASM: &'static str = "examples/callback-guest/callback-guest.wasm"; /// This function matches our arbitrarily decided callback signature /// in this example we'll only call functions that take no arguments and return one value From ca409f78c564c10aa5382e23e59d370d5afc87eb Mon Sep 17 00:00:00 2001 From: Patrick Ventuzelo Date: Fri, 20 Sep 2019 18:54:05 +0200 Subject: [PATCH 20/49] fix spectest --- lib/spectests/examples/simple/main.rs | 8 ++------ lib/spectests/tests/spectest.rs | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/lib/spectests/examples/simple/main.rs b/lib/spectests/examples/simple/main.rs index 357adb5f70d..d7165fe0bc6 100644 --- a/lib/spectests/examples/simple/main.rs +++ b/lib/spectests/examples/simple/main.rs @@ -42,12 +42,8 @@ fn main() -> error::Result<()> { let inner_module = wasmer_runtime_core::compile_with(&wasm_binary, &get_compiler())?; - let memory = Memory::new(MemoryDescriptor { - minimum: Pages(1), - maximum: Some(Pages(1)), - shared: false, - }) - .unwrap(); + let memory_desc = MemoryDescriptor::new(Pages(1),Some(Pages(1)),false).unwrap(); + let memory = Memory::new(memory_desc).unwrap(); let global = Global::new(Value::I32(42)); diff --git a/lib/spectests/tests/spectest.rs b/lib/spectests/tests/spectest.rs index 9cd18d636a8..22bef6ff20c 100644 --- a/lib/spectests/tests/spectest.rs +++ b/lib/spectests/tests/spectest.rs @@ -1056,12 +1056,8 @@ mod tests { fn get_spectest_import_object( registered_modules: &HashMap>, ) -> ImportObject { - let memory = Memory::new(MemoryDescriptor { - minimum: Pages(1), - maximum: Some(Pages(2)), - shared: false, - }) - .unwrap(); + let memory_desc = MemoryDescriptor::new(Pages(1),Some(Pages(2)),false).unwrap(); + let memory = Memory::new(memory_desc).unwrap(); let global_i32 = Global::new(wasmer_runtime_core::types::Value::I32(666)); let global_f32 = Global::new(wasmer_runtime_core::types::Value::F32(666.0)); From 7deed3160b1a49b5b8e5462ae2f5b9c0b0c8a9d6 Mon Sep 17 00:00:00 2001 From: Patrick Ventuzelo Date: Fri, 20 Sep 2019 18:59:36 +0200 Subject: [PATCH 21/49] cargo fmt --- lib/spectests/examples/simple/main.rs | 2 +- lib/spectests/tests/spectest.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/spectests/examples/simple/main.rs b/lib/spectests/examples/simple/main.rs index d7165fe0bc6..e9309c3c295 100644 --- a/lib/spectests/examples/simple/main.rs +++ b/lib/spectests/examples/simple/main.rs @@ -42,7 +42,7 @@ fn main() -> error::Result<()> { let inner_module = wasmer_runtime_core::compile_with(&wasm_binary, &get_compiler())?; - let memory_desc = MemoryDescriptor::new(Pages(1),Some(Pages(1)),false).unwrap(); + let memory_desc = MemoryDescriptor::new(Pages(1), Some(Pages(1)), false).unwrap(); let memory = Memory::new(memory_desc).unwrap(); let global = Global::new(Value::I32(42)); diff --git a/lib/spectests/tests/spectest.rs b/lib/spectests/tests/spectest.rs index 22bef6ff20c..58f31239807 100644 --- a/lib/spectests/tests/spectest.rs +++ b/lib/spectests/tests/spectest.rs @@ -1056,7 +1056,7 @@ mod tests { fn get_spectest_import_object( registered_modules: &HashMap>, ) -> ImportObject { - let memory_desc = MemoryDescriptor::new(Pages(1),Some(Pages(2)),false).unwrap(); + let memory_desc = MemoryDescriptor::new(Pages(1), Some(Pages(2)), false).unwrap(); let memory = Memory::new(memory_desc).unwrap(); let global_i32 = Global::new(wasmer_runtime_core::types::Value::I32(666)); From 882a77ccf9d7f4d112c000ad05babb90dce90198 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 20 Sep 2019 11:59:20 -0700 Subject: [PATCH 22/49] Remove null pointer checks generally, re-add them in Emscripten --- CHANGELOG.md | 1 + lib/emscripten/src/env/mod.rs | 12 +-- lib/emscripten/src/env/unix/mod.rs | 6 +- lib/emscripten/src/env/windows/mod.rs | 3 +- lib/emscripten/src/lib.rs | 1 + lib/emscripten/src/ptr.rs | 113 ++++++++++++++++++++++++++ lib/emscripten/src/syscalls/mod.rs | 10 +-- lib/emscripten/src/syscalls/unix.rs | 4 +- lib/runtime-core/src/memory/ptr.rs | 16 +--- 9 files changed, 136 insertions(+), 30 deletions(-) create mode 100644 lib/emscripten/src/ptr.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 6273bc8ef46..28f596879bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Blocks of changes will separated by version increments. ## **[Unreleased]** +- [#820](https://github.com/wasmerio/wasmer/issues/820) Remove null-pointer checks in `WasmPtr` from runtime-core, re-add them in Emscripten - [#803](https://github.com/wasmerio/wasmer/issues/803) Add method to `Ctx` to invoke functions by their `TableIndex` - [#790](https://github.com/wasmerio/wasmer/pull/790) Fix flaky test failure with LLVM, switch to large code model. - [#788](https://github.com/wasmerio/wasmer/pull/788) Use union merge on the changelog file. diff --git a/lib/emscripten/src/env/mod.rs b/lib/emscripten/src/env/mod.rs index 88fba54a6fc..a61a2bb9f28 100644 --- a/lib/emscripten/src/env/mod.rs +++ b/lib/emscripten/src/env/mod.rs @@ -12,14 +12,14 @@ pub use self::windows::*; use libc::c_char; -use crate::{allocate_on_stack, EmscriptenData}; +use crate::{ + allocate_on_stack, + ptr::{Array, WasmPtr}, + EmscriptenData, +}; use std::os::raw::c_int; -use wasmer_runtime_core::{ - memory::ptr::{Array, WasmPtr}, - types::ValueType, - vm::Ctx, -}; +use wasmer_runtime_core::{types::ValueType, vm::Ctx}; pub fn call_malloc(ctx: &mut Ctx, size: u32) -> u32 { get_emscripten_data(ctx) diff --git a/lib/emscripten/src/env/unix/mod.rs b/lib/emscripten/src/env/unix/mod.rs index 0e62e8e2f62..9516504950d 100644 --- a/lib/emscripten/src/env/unix/mod.rs +++ b/lib/emscripten/src/env/unix/mod.rs @@ -9,11 +9,9 @@ use std::mem; use std::os::raw::c_char; use crate::env::{call_malloc, call_malloc_with_cast, EmAddrInfo, EmSockAddr}; +use crate::ptr::{Array, WasmPtr}; use crate::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs}; -use wasmer_runtime_core::{ - memory::ptr::{Array, WasmPtr}, - vm::Ctx, -}; +use wasmer_runtime_core::vm::Ctx; // #[no_mangle] /// emscripten: _getenv // (name: *const char) -> *const c_char; diff --git a/lib/emscripten/src/env/windows/mod.rs b/lib/emscripten/src/env/windows/mod.rs index d6ba0b0da27..025a01bd742 100644 --- a/lib/emscripten/src/env/windows/mod.rs +++ b/lib/emscripten/src/env/windows/mod.rs @@ -6,8 +6,9 @@ use std::mem; use std::os::raw::c_char; use crate::env::{call_malloc, EmAddrInfo}; +use crate::ptr::WasmPtr; use crate::utils::{copy_cstr_into_wasm, read_string_from_wasm}; -use wasmer_runtime_core::{memory::ptr::WasmPtr, vm::Ctx}; +use wasmer_runtime_core::vm::Ctx; extern "C" { #[link_name = "_putenv"] diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index ba25b4be82a..72740538139 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -62,6 +62,7 @@ mod math; mod memory; mod process; mod pthread; +mod ptr; mod signal; mod storage; mod syscalls; diff --git a/lib/emscripten/src/ptr.rs b/lib/emscripten/src/ptr.rs new file mode 100644 index 00000000000..3c383c3a1af --- /dev/null +++ b/lib/emscripten/src/ptr.rs @@ -0,0 +1,113 @@ +//! This is a wrapper around the `WasmPtr` abstraction that does not allow deref of address 0 +//! This is a common assumption in Emscripten code + +use std::{cell::Cell, fmt}; +pub use wasmer_runtime_core::memory::ptr::Array; +use wasmer_runtime_core::{ + memory::{ptr, Memory}, + types::{ValueType, WasmExternType}, +}; + +#[repr(transparent)] +pub struct WasmPtr(ptr::WasmPtr); + +unsafe impl ValueType for WasmPtr {} +impl Copy for WasmPtr {} + +impl Clone for WasmPtr { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl fmt::Debug for WasmPtr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.0) + } +} + +unsafe impl WasmExternType for WasmPtr { + type Native = as WasmExternType>::Native; + + fn to_native(self) -> Self::Native { + self.0.to_native() + } + fn from_native(n: Self::Native) -> Self { + Self(ptr::WasmPtr::from_native(n)) + } +} + +impl PartialEq for WasmPtr { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl Eq for WasmPtr {} + +impl WasmPtr { + #[inline(always)] + pub fn new(offset: u32) -> Self { + Self(ptr::WasmPtr::new(offset)) + } + + #[inline(always)] + pub fn offset(self) -> u32 { + self.0.offset() + } +} + +impl WasmPtr { + #[inline(always)] + pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a Cell> { + if self.0.offset() == 0 { + None + } else { + self.0.deref(memory) + } + } + + #[inline(always)] + pub unsafe fn deref_mut<'a>(self, memory: &'a Memory) -> Option<&'a mut Cell> { + if self.0.offset() == 0 { + None + } else { + self.0.deref_mut(memory) + } + } +} + +impl WasmPtr { + #[inline(always)] + pub fn deref<'a>(self, memory: &'a Memory, index: u32, length: u32) -> Option<&'a [Cell]> { + if self.0.offset() == 0 { + None + } else { + self.0.deref(memory, index, length) + } + } + + #[inline] + pub unsafe fn deref_mut<'a>( + self, + memory: &'a Memory, + index: u32, + length: u32, + ) -> Option<&'a mut [Cell]> { + if self.0.offset() == 0 { + None + } else { + self.0.deref_mut(memory, index, length) + } + } + + #[allow(dead_code)] + #[inline(always)] + pub fn get_utf8_string<'a>(self, memory: &'a Memory, str_len: u32) -> Option<&'a str> { + if self.0.offset() == 0 { + None + } else { + self.0.get_utf8_string(memory, str_len) + } + } +} diff --git a/lib/emscripten/src/syscalls/mod.rs b/lib/emscripten/src/syscalls/mod.rs index b098bd1529e..ba5965fde34 100644 --- a/lib/emscripten/src/syscalls/mod.rs +++ b/lib/emscripten/src/syscalls/mod.rs @@ -10,7 +10,10 @@ pub use self::unix::*; #[cfg(windows)] pub use self::windows::*; -use crate::utils::{copy_stat_into_wasm, get_cstr_path, get_current_directory}; +use crate::{ + ptr::{Array, WasmPtr}, + utils::{copy_stat_into_wasm, get_cstr_path, get_current_directory}, +}; use super::varargs::VarArgs; use byteorder::{ByteOrder, LittleEndian}; @@ -40,10 +43,7 @@ use libc::{ write, // ENOTTY, }; -use wasmer_runtime_core::{ - memory::ptr::{Array, WasmPtr}, - vm::Ctx, -}; +use wasmer_runtime_core::vm::Ctx; use super::env; use std::cell::Cell; diff --git a/lib/emscripten/src/syscalls/unix.rs b/lib/emscripten/src/syscalls/unix.rs index 000a3e31920..efcff0a5ead 100644 --- a/lib/emscripten/src/syscalls/unix.rs +++ b/lib/emscripten/src/syscalls/unix.rs @@ -1,4 +1,4 @@ -use crate::varargs::VarArgs; +use crate::{ptr::WasmPtr, varargs::VarArgs}; #[cfg(target_os = "macos")] use libc::size_t; /// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32 @@ -111,7 +111,7 @@ fn translate_ioctl(wasm_ioctl: u32) -> c_ulong { #[allow(unused_imports)] use std::ffi::CStr; -use wasmer_runtime_core::{memory::ptr::WasmPtr, vm::Ctx}; +use wasmer_runtime_core::vm::Ctx; use crate::env::EmSockAddr; use crate::utils::{self, get_cstr_path}; diff --git a/lib/runtime-core/src/memory/ptr.rs b/lib/runtime-core/src/memory/ptr.rs index 0a9454acc27..abed45bfb67 100644 --- a/lib/runtime-core/src/memory/ptr.rs +++ b/lib/runtime-core/src/memory/ptr.rs @@ -46,9 +46,7 @@ fn align_pointer(ptr: usize, align: usize) -> usize { impl WasmPtr { #[inline] pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a Cell> { - if self.offset == 0 - || (self.offset as usize) + mem::size_of::() >= memory.size().bytes().0 - { + if (self.offset as usize) + mem::size_of::() >= memory.size().bytes().0 { return None; } unsafe { @@ -62,9 +60,7 @@ impl WasmPtr { #[inline] pub unsafe fn deref_mut<'a>(self, memory: &'a Memory) -> Option<&'a mut Cell> { - if self.offset == 0 - || (self.offset as usize) + mem::size_of::() >= memory.size().bytes().0 - { + if (self.offset as usize) + mem::size_of::() >= memory.size().bytes().0 { return None; } let cell_ptr = align_pointer( @@ -83,9 +79,7 @@ impl WasmPtr { let item_size = mem::size_of::() + (mem::size_of::() % mem::align_of::()); let slice_full_len = index as usize + length as usize; - if self.offset == 0 - || (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0 - { + if (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0 { return None; } @@ -112,9 +106,7 @@ impl WasmPtr { let item_size = mem::size_of::() + (mem::size_of::() % mem::align_of::()); let slice_full_len = index as usize + length as usize; - if self.offset == 0 - || (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0 - { + if (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0 { return None; } From 7f2c5325949a1fc771f4390e3af3800637a437cc Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 20 Sep 2019 13:19:31 -0700 Subject: [PATCH 23/49] Allow dead code in emscripten WasmPtr --- lib/emscripten/src/ptr.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/emscripten/src/ptr.rs b/lib/emscripten/src/ptr.rs index 3c383c3a1af..34cd683648e 100644 --- a/lib/emscripten/src/ptr.rs +++ b/lib/emscripten/src/ptr.rs @@ -1,6 +1,10 @@ //! This is a wrapper around the `WasmPtr` abstraction that does not allow deref of address 0 //! This is a common assumption in Emscripten code +// this is a wrapper with extra logic around the runtime-core `WasmPtr`, so we +// don't want to warn about unusued code here +#![allow(dead_code)] + use std::{cell::Cell, fmt}; pub use wasmer_runtime_core::memory::ptr::Array; use wasmer_runtime_core::{ @@ -101,7 +105,6 @@ impl WasmPtr { } } - #[allow(dead_code)] #[inline(always)] pub fn get_utf8_string<'a>(self, memory: &'a Memory, str_len: u32) -> Option<&'a str> { if self.0.offset() == 0 { From bf396ec76d75336e9ca6eaba3f675f7f2c23401e Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 20 Sep 2019 16:08:45 -0700 Subject: [PATCH 24/49] Remove patch version in deps when not necessary --- CHANGELOG.md | 1 + Cargo.toml | 10 ++++---- lib/clif-backend/Cargo.toml | 16 ++++++------- lib/emscripten-tests/Cargo.toml | 2 +- lib/emscripten/Cargo.toml | 8 +++---- lib/llvm-backend/Cargo.toml | 14 ++++++------ lib/runtime-c-api/Cargo.toml | 2 +- lib/runtime-core/Cargo.toml | 34 ++++++++++++++-------------- lib/runtime/Cargo.toml | 6 ++--- lib/singlepass-backend/Cargo.toml | 8 +++---- lib/spectests/Cargo.toml | 2 +- lib/wasi-tests/Cargo.toml | 2 +- lib/wasi/Cargo.toml | 12 +++++----- lib/win-exception-handler/Cargo.toml | 6 ++--- 14 files changed, 62 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28f596879bf..14f7480991d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Blocks of changes will separated by version increments. ## **[Unreleased]** +- [#821](https://github.com/wasmerio/wasmer/issues/821) Remove patch version on most deps Cargo manifests. This gives Wasmer library users more control over which versions of the deps they use. - [#820](https://github.com/wasmerio/wasmer/issues/820) Remove null-pointer checks in `WasmPtr` from runtime-core, re-add them in Emscripten - [#803](https://github.com/wasmerio/wasmer/issues/803) Add method to `Ctx` to invoke functions by their `TableIndex` - [#790](https://github.com/wasmerio/wasmer/pull/790) Fix flaky test failure with LLVM, switch to large code model. diff --git a/Cargo.toml b/Cargo.toml index 06b2c2854dc..d433ad45630 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,9 +19,9 @@ include = [ ] [dependencies] -byteorder = "1.3.2" -errno = "0.2.4" -structopt = "0.3.0" +byteorder = "1.3" +errno = "0.2" +structopt = "0.3" wabt = "0.9.1" wasmer-clif-backend = { path = "lib/clif-backend" } wasmer-singlepass-backend = { path = "lib/singlepass-backend", optional = true } @@ -63,8 +63,8 @@ members = [ [build-dependencies] wabt = "0.9.1" -glob = "0.3.0" -rustc_version = "0.2.3" +glob = "0.3" +rustc_version = "0.2" [dev-dependencies] serde = { version = "1", features = ["derive"] } # used by the plugin example diff --git a/lib/clif-backend/Cargo.toml b/lib/clif-backend/Cargo.toml index be48208c7c5..3b662358d87 100644 --- a/lib/clif-backend/Cargo.toml +++ b/lib/clif-backend/Cargo.toml @@ -15,26 +15,26 @@ cranelift-codegen = { version = "0.31" } cranelift-entity = { version = "0.31" } cranelift-frontend = { package = "wasmer-clif-fork-frontend", version = "0.33" } cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.33" } -target-lexicon = "0.4.0" +target-lexicon = "0.4" wasmparser = "0.35.1" -byteorder = "1.3.2" -nix = "0.15.0" +byteorder = "1.3" +nix = "0.15" libc = "0.2.60" -rayon = "1.1.0" +rayon = "1.1" # Dependencies for caching. [dependencies.serde] -version = "1.0.99" +version = "1.0" features = ["rc"] [dependencies.serde_derive] -version = "1.0.98" +version = "1.0" [dependencies.serde_bytes] -version = "0.11.2" +version = "0.11" [dependencies.serde-bench] version = "0.0.7" [target.'cfg(windows)'.dependencies] -winapi = { version = "0.3.8", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] } +winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] } wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.7.0" } [features] diff --git a/lib/emscripten-tests/Cargo.toml b/lib/emscripten-tests/Cargo.toml index 8c5f6c93e74..2954e84fbe5 100644 --- a/lib/emscripten-tests/Cargo.toml +++ b/lib/emscripten-tests/Cargo.toml @@ -20,7 +20,7 @@ wabt = "0.9.1" wasmer-dev-utils = { path = "../dev-utils", version = "0.7.0"} [build-dependencies] -glob = "0.3.0" +glob = "0.3" [features] clif = [] diff --git a/lib/emscripten/Cargo.toml b/lib/emscripten/Cargo.toml index f547e640e56..f5b6222b2db 100644 --- a/lib/emscripten/Cargo.toml +++ b/lib/emscripten/Cargo.toml @@ -8,14 +8,14 @@ repository = "https://github.com/wasmerio/wasmer" edition = "2018" [dependencies] -byteorder = "1.3.2" -lazy_static = "1.4.0" +byteorder = "1.3" +lazy_static = "1.4" libc = "0.2.60" -time = "0.1.42" +time = "0.1" wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" } [target.'cfg(windows)'.dependencies] -rand = "0.7.0" +rand = "0.7" [features] debug = ["wasmer-runtime-core/debug"] diff --git a/lib/llvm-backend/Cargo.toml b/lib/llvm-backend/Cargo.toml index ca4e1e51ea6..2e198a6c39f 100644 --- a/lib/llvm-backend/Cargo.toml +++ b/lib/llvm-backend/Cargo.toml @@ -8,10 +8,10 @@ readme = "README.md" [dependencies] wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" } wasmparser = "0.35.1" -smallvec = "0.6.10" +smallvec = "0.6" goblin = "0.0.24" libc = "0.2.60" -capstone = { version = "0.6.0", optional = true } +capstone = { version = "0.6", optional = true } byteorder = "1" [dependencies.inkwell] @@ -21,17 +21,17 @@ default-features = false features = ["llvm8-0", "target-x86"] [target.'cfg(unix)'.dependencies] -nix = "0.15.0" +nix = "0.15" [target.'cfg(windows)'.dependencies] -winapi = { version = "0.3.8", features = ["memoryapi"] } +winapi = { version = "0.3", features = ["memoryapi"] } [build-dependencies] cc = "1.0" -lazy_static = "1.4.0" -regex = "1.2.1" +lazy_static = "1.4" +regex = "1.2" semver = "0.9" -rustc_version = "0.2.3" +rustc_version = "0.2" [dev-dependencies] wabt = "0.9.1" diff --git a/lib/runtime-c-api/Cargo.toml b/lib/runtime-c-api/Cargo.toml index 8aac30da31e..bcfa4bec5d1 100644 --- a/lib/runtime-c-api/Cargo.toml +++ b/lib/runtime-c-api/Cargo.toml @@ -32,4 +32,4 @@ llvm-backend = ["wasmer-runtime/llvm", "wasmer-runtime/default-backend-llvm"] singlepass-backend = ["wasmer-runtime/singlepass", "wasmer-runtime/default-backend-singlepass"] [build-dependencies] -cbindgen = "0.9.1" +cbindgen = "0.9" diff --git a/lib/runtime-core/Cargo.toml b/lib/runtime-core/Cargo.toml index 9349a7c6407..f683a974eb5 100644 --- a/lib/runtime-core/Cargo.toml +++ b/lib/runtime-core/Cargo.toml @@ -8,46 +8,46 @@ repository = "https://github.com/wasmerio/wasmer" edition = "2018" [dependencies] -nix = "0.15.0" -page_size = "0.4.1" +nix = "0.15" +page_size = "0.4" wasmparser = "0.35.1" -parking_lot = "0.9.0" -lazy_static = "1.4.0" -errno = "0.2.4" +parking_lot = "0.9" +lazy_static = "1.4" +errno = "0.2" libc = "0.2.60" -hex = "0.3.2" -smallvec = "0.6.10" +hex = "0.3" +smallvec = "0.6" bincode = "1.1" [dependencies.indexmap] -version = "1.2.0" +version = "1.2" features = ["serde-1"] # Dependencies for caching. [dependencies.serde] -version = "1.0.99" +version = "1.0" # This feature is required for serde to support serializing/deserializing reference counted pointers (e.g. Rc and Arc). features = ["rc"] [dependencies.serde_derive] -version = "1.0.98" +version = "1.0" [dependencies.serde_bytes] -version = "0.11.2" +version = "0.11" [dependencies.serde-bench] version = "0.0.7" [dependencies.blake2b_simd] -version = "0.5.8" +version = "0.5" [dependencies.digest] -version = "0.8.1" +version = "0.8" [target.'cfg(windows)'.dependencies] -winapi = { version = "0.3.8", features = ["memoryapi"] } +winapi = { version = "0.3", features = ["memoryapi"] } [dev-dependencies] -field-offset = "0.1.1" +field-offset = "0.1" [build-dependencies] -blake2b_simd = "0.5.8" -rustc_version = "0.2.3" +blake2b_simd = "0.5" +rustc_version = "0.2" cc = "1.0" [features] diff --git a/lib/runtime/Cargo.toml b/lib/runtime/Cargo.toml index 2321cf99607..29b90955e03 100644 --- a/lib/runtime/Cargo.toml +++ b/lib/runtime/Cargo.toml @@ -10,8 +10,8 @@ readme = "README.md" [dependencies] wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.7.0", optional = true } -lazy_static = "1.4.0" -memmap = "0.7.0" +lazy_static = "1.4" +memmap = "0.7" [dependencies.wasmer-runtime-core] path = "../runtime-core" @@ -23,7 +23,7 @@ version = "0.7.0" optional = true [dev-dependencies] -tempfile = "3.1.0" +tempfile = "3.1" criterion = "0.2" wabt = "0.9.1" diff --git a/lib/singlepass-backend/Cargo.toml b/lib/singlepass-backend/Cargo.toml index 65bfd54bcc7..f90afad1278 100644 --- a/lib/singlepass-backend/Cargo.toml +++ b/lib/singlepass-backend/Cargo.toml @@ -13,8 +13,8 @@ wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" } wasmparser = "0.35.1" dynasm = "0.3.2" dynasmrt = "0.3.1" -lazy_static = "1.4.0" -byteorder = "1.3.2" -nix = "0.15.0" +lazy_static = "1.4" +byteorder = "1.3" +nix = "0.15" libc = "0.2.60" -smallvec = "0.6.10" +smallvec = "0.6" diff --git a/lib/spectests/Cargo.toml b/lib/spectests/Cargo.toml index feab4eccbda..7b3e6adbea7 100644 --- a/lib/spectests/Cargo.toml +++ b/lib/spectests/Cargo.toml @@ -8,7 +8,7 @@ repository = "https://github.com/wasmerio/wasmer" edition = "2018" [dependencies] -glob = "0.3.0" +glob = "0.3" wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" } wasmer-clif-backend = { path = "../clif-backend", version = "0.7.0" } wasmer-llvm-backend = { path = "../llvm-backend", version = "0.7.0", optional = true } diff --git a/lib/wasi-tests/Cargo.toml b/lib/wasi-tests/Cargo.toml index 7b092710190..9462fc73173 100644 --- a/lib/wasi-tests/Cargo.toml +++ b/lib/wasi-tests/Cargo.toml @@ -18,7 +18,7 @@ wasmer-llvm-backend = { path = "../llvm-backend", version = "0.7.0", optional = [build-dependencies] -glob = "0.3.0" +glob = "0.3" [dev-dependencies] wasmer-clif-backend = { path = "../clif-backend", version = "0.7.0" } diff --git a/lib/wasi/Cargo.toml b/lib/wasi/Cargo.toml index 70bdd69966c..af65b65e86a 100644 --- a/lib/wasi/Cargo.toml +++ b/lib/wasi/Cargo.toml @@ -9,16 +9,16 @@ edition = "2018" [dependencies] bincode = "1" -byteorder = "1.3.2" -generational-arena = { version = "0.2.2", features = ["serde"] } +byteorder = "1.3" +generational-arena = { version = "0.2", features = ["serde"] } libc = "0.2.60" -log = "0.4.8" -rand = "0.7.0" -time = "0.1.42" +log = "0.4" +rand = "0.7" +time = "0.1" typetag = "0.1" serde = { version = "1", features = ["derive"] } # wasmer-runtime-abi = { path = "../runtime-abi" } wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" } [target.'cfg(windows)'.dependencies] -winapi = "0.3.8" +winapi = "0.3" diff --git a/lib/win-exception-handler/Cargo.toml b/lib/win-exception-handler/Cargo.toml index dd67b673328..4254ee5ae47 100644 --- a/lib/win-exception-handler/Cargo.toml +++ b/lib/win-exception-handler/Cargo.toml @@ -13,6 +13,6 @@ winapi = { version = "0.3.8", features = ["winbase", "errhandlingapi", "minwinde libc = "0.2.60" [build-dependencies] -cmake = "0.1.40" -bindgen = "0.51.0" -regex = "1.2.1" +cmake = "0.1" +bindgen = "0.51" +regex = "1.2" From c09e0e06dfd98f57aa2267c555bf4bda3276f030 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 20 Sep 2019 17:01:41 -0700 Subject: [PATCH 25/49] Update feature matrix --- CHANGELOG.md | 1 + docs/feature_matrix.md | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1651f7ffbeb..9f800b7a2e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Blocks of changes will separated by version increments. ## **[Unreleased]** +- [#817](https://github.com/wasmerio/wasmer/pull/817) Add document for tracking features across backends and language integrations, [docs/feature_matrix.md] - [#790](https://github.com/wasmerio/wasmer/pull/790) Fix flaky test failure with LLVM, switch to large code model. - [#788](https://github.com/wasmerio/wasmer/pull/788) Use union merge on the changelog file. - [#785](https://github.com/wasmerio/wasmer/pull/785) Include Apache license file for spectests. diff --git a/docs/feature_matrix.md b/docs/feature_matrix.md index 51808065b09..abca531d6d2 100644 --- a/docs/feature_matrix.md +++ b/docs/feature_matrix.md @@ -4,9 +4,10 @@ |   | Singlepass | Cranelift | LLVM | | - | - | - | - | -| Caching | No | Yes | Yes | -| SIMD | No | No | Yes | -| Multi-value return | No | No | No | +| Caching | ❌ | ✅ | ✅ | +| SIMD | ❌ | ❌ | ✅ | +| Multi-value return | ❌ | ❌ | ❌ | +| Metering | ✅ | ✅ | ❓ | ## Language integration @@ -16,5 +17,7 @@ TODO: define a set of features that are relevant and mark them here Current ideas: - WASI FS API -- Callbacks? (not even in Rust yet) +- Callbacks - Exiting early in hostcall +- Metering +- Caching From f48d6f6690794ae67de1e6ba4dcb15e68fd0d6e3 Mon Sep 17 00:00:00 2001 From: Brandon Fish Date: Sat, 21 Sep 2019 13:06:54 -0500 Subject: [PATCH 26/49] Cranelift backend update to fork of clif version 0.43.1 --- Cargo.lock | 128 +++++++++++++++-------------- lib/clif-backend/Cargo.toml | 18 ++-- lib/clif-backend/src/code.rs | 13 ++- lib/clif-backend/src/lib.rs | 4 +- lib/clif-backend/src/relocation.rs | 5 ++ lib/clif-backend/src/resolver.rs | 13 ++- lib/clif-backend/src/trampoline.rs | 9 +- lib/llvm-backend/Cargo.toml | 2 +- lib/runtime-abi/Cargo.toml | 2 +- lib/runtime-core/Cargo.toml | 2 +- lib/runtime-core/src/codegen.rs | 1 - lib/runtime-core/src/lib.rs | 1 - lib/singlepass-backend/Cargo.toml | 2 +- 13 files changed, 116 insertions(+), 84 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3d8c85a48c9..3270ab2f7ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -247,47 +247,73 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cranelift-bforest" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.43.1" +source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" dependencies = [ - "cranelift-entity 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-entity 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", ] [[package]] name = "cranelift-codegen" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.43.1" +source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" dependencies = [ - "cranelift-bforest 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-codegen-meta 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-entity 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-bforest 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-codegen-meta 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-entity 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cranelift-codegen-meta" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.43.1" +source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" dependencies = [ - "cranelift-entity 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-entity 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", ] [[package]] name = "cranelift-entity" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.43.1" +source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" + +[[package]] +name = "cranelift-frontend" +version = "0.43.1" +source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" +dependencies = [ + "cranelift-codegen 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "cranelift-native" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.43.1" +source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" dependencies = [ - "cranelift-codegen 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-codegen 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", "raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cranelift-wasm" +version = "0.43.1" +source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" +dependencies = [ + "cranelift-codegen 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-entity 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-frontend 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmparser 0.37.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1269,7 +1295,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "target-lexicon" -version = "0.4.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1484,9 +1510,11 @@ name = "wasmer-clif-backend" version = "0.7.0" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-codegen 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-entity 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-native 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-codegen 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-entity 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-frontend 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-native 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-wasm 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1494,39 +1522,13 @@ dependencies = [ "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", - "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-clif-fork-frontend 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-clif-fork-wasm 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.7.0", "wasmer-win-exception-handler 0.7.0", - "wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmparser 0.37.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "wasmer-clif-fork-frontend" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cranelift-codegen 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasmer-clif-fork-wasm" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cranelift-codegen 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-entity 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-clif-fork-frontend 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "wasmer-dev-utils" version = "0.7.0" @@ -1586,7 +1588,7 @@ dependencies = [ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.7.0", - "wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmparser 0.37.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1658,7 +1660,7 @@ dependencies = [ "serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmparser 0.37.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1674,7 +1676,7 @@ dependencies = [ "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.7.0", - "wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmparser 0.37.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1734,7 +1736,7 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.35.3" +version = "0.37.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1821,11 +1823,13 @@ dependencies = [ "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" "checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" -"checksum cranelift-bforest 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "409f92af3dd276e112b72873a3ef02613e3c5f55b81d5d5d04f3157d4f8b8c54" -"checksum cranelift-codegen 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b303542a56fba4cbaeea099fb30ed078b50de0e765fd69f7f5f410adbe31d95b" -"checksum cranelift-codegen-meta 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0fee15ed430092a6d14b7c6d627540bef732509b8097ae31e4e35526edaa129c" -"checksum cranelift-entity 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "739222c3740e4a8d6f0375bd95caba9b6c11afcba9f0e1d4f944d6bd99f84600" -"checksum cranelift-native 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce451162d18b7d82118e23ea7e12f7d8b98557549404bd71215548de79eb0736" +"checksum cranelift-bforest 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" +"checksum cranelift-codegen 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" +"checksum cranelift-codegen-meta 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" +"checksum cranelift-entity 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" +"checksum cranelift-frontend 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" +"checksum cranelift-native 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" +"checksum cranelift-wasm 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" "checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394" "checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" @@ -1940,7 +1944,7 @@ dependencies = [ "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" -"checksum target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b0ab4982b8945c35cc1c46a83a9094c414f6828a099ce5dcaa8ee2b04642dcb" +"checksum target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7975cb2c6f37d77b190bc5004a2bb015971464756fde9514651a525ada2a741a" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" @@ -1964,9 +1968,7 @@ dependencies = [ "checksum wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af5d153dc96aad7dc13ab90835b892c69867948112d95299e522d370c4e13a08" "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" -"checksum wasmer-clif-fork-frontend 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bd6bec1587a3b11222f4ff129fd119785713c41de413f54f99d3c03743812f4" -"checksum wasmer-clif-fork-wasm 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f323e612fe2549391255a09f89c927d7feb0ec4bf0c2cad9e3c089bdca42fc" -"checksum wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)" = "099aaf77635ffad3d9ab57253c29b16a46e93755c3e54cfe33fb8cf4b54f760b" +"checksum wasmparser 0.37.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7387ba67c13dd9cd01d7d961e733375aee889f828564e190da85b5602eb5eeb" "checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" diff --git a/lib/clif-backend/Cargo.toml b/lib/clif-backend/Cargo.toml index 3b662358d87..901223de9ca 100644 --- a/lib/clif-backend/Cargo.toml +++ b/lib/clif-backend/Cargo.toml @@ -10,15 +10,15 @@ readme = "README.md" [dependencies] wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" } -cranelift-native = { version = "0.31" } -cranelift-codegen = { version = "0.31" } -cranelift-entity = { version = "0.31" } -cranelift-frontend = { package = "wasmer-clif-fork-frontend", version = "0.33" } -cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.33" } -target-lexicon = "0.4" -wasmparser = "0.35.1" -byteorder = "1.3" -nix = "0.15" +cranelift-native = { git = "https://github.com/wasmerio/cranelift", branch = "feature/merge-cranelift-0-43-1" } +cranelift-codegen = { git = "https://github.com/wasmerio/cranelift", branch = "feature/merge-cranelift-0-43-1" } +cranelift-entity = { git = "https://github.com/wasmerio/cranelift", branch = "feature/merge-cranelift-0-43-1" } +cranelift-frontend = { git = "https://github.com/wasmerio/cranelift", branch = "feature/merge-cranelift-0-43-1" } +cranelift-wasm = { git = "https://github.com/wasmerio/cranelift", branch = "feature/merge-cranelift-0-43-1" } +target-lexicon = "0.8.1" +wasmparser = { version = "0.37.0", default-features = false } +byteorder = "1.3.2" +nix = "0.15.0" libc = "0.2.60" rayon = "1.1" diff --git a/lib/clif-backend/src/code.rs b/lib/clif-backend/src/code.rs index f5e4b3b7a01..b2ccc66520a 100644 --- a/lib/clif-backend/src/code.rs +++ b/lib/clif-backend/src/code.rs @@ -1117,7 +1117,18 @@ impl FunctionCodeGenerator for CraneliftFunctionCodeGenerator { fn feed_local(&mut self, ty: WpType, n: usize) -> Result<(), CodegenError> { let mut next_local = self.next_local; - cranelift_wasm::declare_locals(&mut self.builder(), n as u32, ty, &mut next_local)?; + let mut builder = FunctionBuilder::new( + &mut self.func, + &mut self.func_translator.func_ctx, + &mut self.position, + ); + cranelift_wasm::declare_locals( + &mut builder, + n as u32, + ty, + &mut next_local, + &mut self.func_env, + )?; self.next_local = next_local; Ok(()) } diff --git a/lib/clif-backend/src/lib.rs b/lib/clif-backend/src/lib.rs index 60f19a877ed..ddecdbaf08a 100644 --- a/lib/clif-backend/src/lib.rs +++ b/lib/clif-backend/src/lib.rs @@ -34,7 +34,7 @@ extern crate serde; fn get_isa() -> Box { let flags = { let mut builder = settings::builder(); - builder.set("opt_level", "best").unwrap(); + builder.set("opt_level", "speed_and_size").unwrap(); builder.set("jump_tables_enabled", "false").unwrap(); if cfg!(not(test)) { @@ -42,7 +42,7 @@ fn get_isa() -> Box { } let flags = settings::Flags::new(builder); - debug_assert_eq!(flags.opt_level(), settings::OptLevel::Best); + debug_assert_eq!(flags.opt_level(), settings::OptLevel::SpeedAndSize); flags }; isa::lookup(Triple::host()).unwrap().finish(flags) diff --git a/lib/clif-backend/src/relocation.rs b/lib/clif-backend/src/relocation.rs index 50a032095ec..bb07c7c59b3 100644 --- a/lib/clif-backend/src/relocation.rs +++ b/lib/clif-backend/src/relocation.rs @@ -202,6 +202,11 @@ impl binemit::RelocSink for RelocSink { } } } + + fn reloc_constant(&mut self, _: u32, _: cranelift_codegen::binemit::Reloc, _: u32) { + unimplemented!() + } + fn reloc_jt( &mut self, _offset: binemit::CodeOffset, diff --git a/lib/clif-backend/src/resolver.rs b/lib/clif-backend/src/resolver.rs index 94e984fb6fe..7a868f35e46 100644 --- a/lib/clif-backend/src/resolver.rs +++ b/lib/clif-backend/src/resolver.rs @@ -10,7 +10,10 @@ use crate::{ use rayon::prelude::*; use byteorder::{ByteOrder, LittleEndian}; -use cranelift_codegen::{ir, isa, Context}; +use cranelift_codegen::{ + binemit::{Stackmap, StackmapSink}, + ir, isa, Context, +}; use std::{ mem, ptr::{write_unaligned, NonNull}, @@ -58,6 +61,11 @@ pub struct FuncResolverBuilder { import_len: usize, } +pub struct NoopStackmapSink {} +impl StackmapSink for NoopStackmapSink { + fn add_stackmap(&mut self, _: u32, _: Stackmap) {} +} + impl FuncResolverBuilder { pub fn new_from_backend_cache( backend_cache: BackendCache, @@ -109,12 +117,13 @@ impl FuncResolverBuilder { ctx.func = func.to_owned(); let mut reloc_sink = RelocSink::new(); let mut local_trap_sink = LocalTrapSink::new(); - + let mut stackmap_sink = NoopStackmapSink {}; ctx.compile_and_emit( isa, &mut code_buf, &mut reloc_sink, &mut local_trap_sink, + &mut stackmap_sink, ) .map_err(|e| CompileError::InternalError { msg: e.to_string() })?; ctx.clear(); diff --git a/lib/clif-backend/src/trampoline.rs b/lib/clif-backend/src/trampoline.rs index 7f22c62a5bd..a6fc6572bac 100644 --- a/lib/clif-backend/src/trampoline.rs +++ b/lib/clif-backend/src/trampoline.rs @@ -1,4 +1,5 @@ use crate::cache::TrampolineCache; +use crate::resolver::NoopStackmapSink; use cranelift_codegen::{ binemit::{NullTrapSink, Reloc, RelocSink}, cursor::{Cursor, FuncCursor}, @@ -19,6 +20,11 @@ struct NullRelocSink {} impl RelocSink for NullRelocSink { fn reloc_ebb(&mut self, _: u32, _: Reloc, _: u32) {} fn reloc_external(&mut self, _: u32, _: Reloc, _: &ir::ExternalName, _: i64) {} + + fn reloc_constant(&mut self, _: u32, _: Reloc, _: u32) { + unimplemented!() + } + fn reloc_jt(&mut self, _: u32, _: Reloc, _: ir::JumpTable) {} } @@ -89,12 +95,13 @@ impl Trampolines { ctx.func = trampoline_func; let mut code_buf = Vec::new(); - + let mut stackmap_sink = NoopStackmapSink {}; ctx.compile_and_emit( isa, &mut code_buf, &mut NullRelocSink {}, &mut NullTrapSink {}, + &mut stackmap_sink, ) .expect("unable to compile trampolines"); ctx.clear(); diff --git a/lib/llvm-backend/Cargo.toml b/lib/llvm-backend/Cargo.toml index 2e198a6c39f..bd97176f958 100644 --- a/lib/llvm-backend/Cargo.toml +++ b/lib/llvm-backend/Cargo.toml @@ -7,7 +7,7 @@ readme = "README.md" [dependencies] wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" } -wasmparser = "0.35.1" +wasmparser = { version = "0.37.0", default-features = false } smallvec = "0.6" goblin = "0.0.24" libc = "0.2.60" diff --git a/lib/runtime-abi/Cargo.toml b/lib/runtime-abi/Cargo.toml index 1840e65d904..d0cda4124c3 100644 --- a/lib/runtime-abi/Cargo.toml +++ b/lib/runtime-abi/Cargo.toml @@ -12,7 +12,7 @@ libc = "0.2.60" wasmer-runtime-core = { path = "../runtime-core" } failure = "0.1" tar = "0.4" -wasmparser = "0.35.1" +wasmparser = { version = "0.37.0", default-features = false } zstd = "0.4" # [target.'cfg(unix)'.dependencies.zbox] diff --git a/lib/runtime-core/Cargo.toml b/lib/runtime-core/Cargo.toml index f683a974eb5..02d5b62c3a2 100644 --- a/lib/runtime-core/Cargo.toml +++ b/lib/runtime-core/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" [dependencies] nix = "0.15" page_size = "0.4" -wasmparser = "0.35.1" +wasmparser = { version = "0.37.0", default-features = false } parking_lot = "0.9" lazy_static = "1.4" errno = "0.2" diff --git a/lib/runtime-core/src/codegen.rs b/lib/runtime-core/src/codegen.rs index e69b9637c6b..3db1b374368 100644 --- a/lib/runtime-core/src/codegen.rs +++ b/lib/runtime-core/src/codegen.rs @@ -146,7 +146,6 @@ pub fn validating_parser_config(features: &Features) -> wasmparser::ValidatingPa enable_bulk_memory: false, enable_multi_value: false, }, - mutable_global_imports: true, } } diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index fa4450693ee..26a76f7dbf6 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -146,7 +146,6 @@ pub fn validate_and_report_errors_with_features( enable_reference_types: false, enable_threads: features.threads, }, - mutable_global_imports: true, }; let mut parser = wasmparser::ValidatingParser::new(wasm, Some(config)); loop { diff --git a/lib/singlepass-backend/Cargo.toml b/lib/singlepass-backend/Cargo.toml index f90afad1278..573018e14b0 100644 --- a/lib/singlepass-backend/Cargo.toml +++ b/lib/singlepass-backend/Cargo.toml @@ -10,7 +10,7 @@ readme = "README.md" [dependencies] wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" } -wasmparser = "0.35.1" +wasmparser = { version = "0.37.0", default-features = false } dynasm = "0.3.2" dynasmrt = "0.3.1" lazy_static = "1.4" From a1a88c6eb8bd63f16fb7b415169e3cd125a4154e Mon Sep 17 00:00:00 2001 From: Brandon Fish Date: Sat, 21 Sep 2019 13:59:08 -0500 Subject: [PATCH 27/49] Use the default features for wasmparser --- lib/clif-backend/Cargo.toml | 2 +- lib/llvm-backend/Cargo.toml | 2 +- lib/runtime-abi/Cargo.toml | 2 +- lib/runtime-core/Cargo.toml | 2 +- lib/singlepass-backend/Cargo.toml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/clif-backend/Cargo.toml b/lib/clif-backend/Cargo.toml index 901223de9ca..3aa7f735e86 100644 --- a/lib/clif-backend/Cargo.toml +++ b/lib/clif-backend/Cargo.toml @@ -16,7 +16,7 @@ cranelift-entity = { git = "https://github.com/wasmerio/cranelift", branch = "fe cranelift-frontend = { git = "https://github.com/wasmerio/cranelift", branch = "feature/merge-cranelift-0-43-1" } cranelift-wasm = { git = "https://github.com/wasmerio/cranelift", branch = "feature/merge-cranelift-0-43-1" } target-lexicon = "0.8.1" -wasmparser = { version = "0.37.0", default-features = false } +wasmparser = "0.37.0" byteorder = "1.3.2" nix = "0.15.0" libc = "0.2.60" diff --git a/lib/llvm-backend/Cargo.toml b/lib/llvm-backend/Cargo.toml index bd97176f958..daf93332663 100644 --- a/lib/llvm-backend/Cargo.toml +++ b/lib/llvm-backend/Cargo.toml @@ -7,7 +7,7 @@ readme = "README.md" [dependencies] wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" } -wasmparser = { version = "0.37.0", default-features = false } +wasmparser = "0.37.0" smallvec = "0.6" goblin = "0.0.24" libc = "0.2.60" diff --git a/lib/runtime-abi/Cargo.toml b/lib/runtime-abi/Cargo.toml index d0cda4124c3..9779adbd080 100644 --- a/lib/runtime-abi/Cargo.toml +++ b/lib/runtime-abi/Cargo.toml @@ -12,7 +12,7 @@ libc = "0.2.60" wasmer-runtime-core = { path = "../runtime-core" } failure = "0.1" tar = "0.4" -wasmparser = { version = "0.37.0", default-features = false } +wasmparser = "0.37.0" zstd = "0.4" # [target.'cfg(unix)'.dependencies.zbox] diff --git a/lib/runtime-core/Cargo.toml b/lib/runtime-core/Cargo.toml index 02d5b62c3a2..8ebea6a77b2 100644 --- a/lib/runtime-core/Cargo.toml +++ b/lib/runtime-core/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" [dependencies] nix = "0.15" page_size = "0.4" -wasmparser = { version = "0.37.0", default-features = false } +wasmparser = "0.37.0" parking_lot = "0.9" lazy_static = "1.4" errno = "0.2" diff --git a/lib/singlepass-backend/Cargo.toml b/lib/singlepass-backend/Cargo.toml index 573018e14b0..a78e037e157 100644 --- a/lib/singlepass-backend/Cargo.toml +++ b/lib/singlepass-backend/Cargo.toml @@ -10,7 +10,7 @@ readme = "README.md" [dependencies] wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" } -wasmparser = { version = "0.37.0", default-features = false } +wasmparser = "0.37.0" dynasm = "0.3.2" dynasmrt = "0.3.1" lazy_static = "1.4" From 0671311bd7428491d131bfa4ae0fcd0baf0d376b Mon Sep 17 00:00:00 2001 From: Brandon Fish Date: Sat, 21 Sep 2019 14:35:29 -0500 Subject: [PATCH 28/49] Add cranelift update to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14f7480991d..681d3f2d7cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Blocks of changes will separated by version increments. ## **[Unreleased]** +- [#822](https://github.com/wasmerio/wasmer/pull/822) Update Cranelift fork version to `0.43.1` - [#821](https://github.com/wasmerio/wasmer/issues/821) Remove patch version on most deps Cargo manifests. This gives Wasmer library users more control over which versions of the deps they use. - [#820](https://github.com/wasmerio/wasmer/issues/820) Remove null-pointer checks in `WasmPtr` from runtime-core, re-add them in Emscripten - [#803](https://github.com/wasmerio/wasmer/issues/803) Add method to `Ctx` to invoke functions by their `TableIndex` From 009c12333225963c44da056976d0a59d8a9b5dda Mon Sep 17 00:00:00 2001 From: Azure Pipelines Date: Sun, 22 Sep 2019 17:29:12 -0700 Subject: [PATCH 29/49] Fixed emscripten main functions --- lib/emscripten/src/lib.rs | 6 +++++- lib/emscripten/src/math.rs | 15 +++++++++++++++ lib/emscripten/src/process.rs | 21 +++++++-------------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index 72740538139..e0be391a767 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -735,8 +735,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject "___syscall345" => func!(crate::syscalls::___syscall345), // Process - "abort" => func!(crate::process::em_abort), + "abort" => func!(crate::process::_abort), "_abort" => func!(crate::process::_abort), + "_prctl" => func!(crate::process::_prctl), "abortStackOverflow" => func!(crate::process::abort_stack_overflow), "_llvm_trap" => func!(crate::process::_llvm_trap), "_fork" => func!(crate::process::_fork), @@ -829,6 +830,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject "_gmtime" => func!(crate::time::_gmtime), // Math + "sqrt" => func!(crate::math::sqrt), + "floor" => func!(crate::math::floor), + "fabs" => func!(crate::math::fabs), "f64-rem" => func!(crate::math::f64_rem), "_llvm_copysign_f32" => func!(crate::math::_llvm_copysign_f32), "_llvm_copysign_f64" => func!(crate::math::_llvm_copysign_f64), diff --git a/lib/emscripten/src/math.rs b/lib/emscripten/src/math.rs index 3aea6f8b7a7..914411ee93b 100644 --- a/lib/emscripten/src/math.rs +++ b/lib/emscripten/src/math.rs @@ -88,6 +88,21 @@ pub fn log(_ctx: &mut Ctx, value: f64) -> f64 { value.ln() } +// emscripten: global.Math sqrt +pub fn sqrt(_ctx: &mut Ctx, value: f64) -> f64 { + value.sqrt() +} + +// emscripten: global.Math floor +pub fn floor(_ctx: &mut Ctx, value: f64) -> f64 { + value.floor() +} + +// emscripten: global.Math fabs +pub fn fabs(_ctx: &mut Ctx, value: f64) -> f64 { + value.abs() +} + // emscripten: asm2wasm.f64-to-int pub fn f64_to_int(_ctx: &mut Ctx, value: f64) -> i32 { debug!("emscripten::f64_to_int {}", value); diff --git a/lib/emscripten/src/process.rs b/lib/emscripten/src/process.rs index cd083e94327..a776734b454 100644 --- a/lib/emscripten/src/process.rs +++ b/lib/emscripten/src/process.rs @@ -1,11 +1,10 @@ -use libc::{abort, c_char, c_int, exit, EAGAIN}; +use libc::{abort, c_int, exit, EAGAIN}; #[cfg(not(target_os = "windows"))] type PidT = libc::pid_t; #[cfg(target_os = "windows")] type PidT = c_int; -use std::ffi::CStr; use wasmer_runtime_core::vm::Ctx; pub fn abort_with_message(ctx: &mut Ctx, message: &str) { @@ -21,6 +20,12 @@ pub fn _abort(_ctx: &mut Ctx) { } } +pub fn _prctl(ctx: &mut Ctx, _a: i32, _b: i32) -> i32 { + debug!("emscripten::_prctl"); + abort_with_message(ctx, "missing function: prctl"); + -1 +} + pub fn _fork(_ctx: &mut Ctx) -> PidT { debug!("emscripten::_fork"); // unsafe { @@ -45,18 +50,6 @@ pub fn _exit(_ctx: &mut Ctx, status: c_int) { unsafe { exit(status) } } -pub fn em_abort(ctx: &mut Ctx, message: u32) { - debug!("emscripten::em_abort {}", message); - let message_addr = emscripten_memory_pointer!(ctx.memory(0), message) as *mut c_char; - unsafe { - let message = CStr::from_ptr(message_addr) - .to_str() - .unwrap_or("Unexpected abort"); - - abort_with_message(ctx, message); - } -} - pub fn _kill(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::_kill"); -1 From 8e2f526f73794028a776dca353e5fdb83203d7c6 Mon Sep 17 00:00:00 2001 From: Azure Pipelines Date: Sun, 22 Sep 2019 17:42:19 -0700 Subject: [PATCH 30/49] Added cpp example --- lib/emscripten-tests/emtests/issue_577.cpp | 6 ++++++ lib/emscripten-tests/emtests/issue_577.wasm | Bin 0 -> 160324 bytes 2 files changed, 6 insertions(+) create mode 100644 lib/emscripten-tests/emtests/issue_577.cpp create mode 100644 lib/emscripten-tests/emtests/issue_577.wasm diff --git a/lib/emscripten-tests/emtests/issue_577.cpp b/lib/emscripten-tests/emtests/issue_577.cpp new file mode 100644 index 00000000000..3b53ca60bbf --- /dev/null +++ b/lib/emscripten-tests/emtests/issue_577.cpp @@ -0,0 +1,6 @@ +#include + +int main(int argc, char* argv[]) { + std::cout << "Does this work?" << std::endl; + return 0; +} diff --git a/lib/emscripten-tests/emtests/issue_577.wasm b/lib/emscripten-tests/emtests/issue_577.wasm new file mode 100644 index 0000000000000000000000000000000000000000..5e3d8ca8a453cde80afa1bf8b189f768129b4b66 GIT binary patch literal 160324 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 literal 0 HcmV?d00001 From bafd318284066ffeb99f0c67d0db0d8431a94a01 Mon Sep 17 00:00:00 2001 From: Syrus Date: Sun, 22 Sep 2019 17:46:16 -0700 Subject: [PATCH 31/49] Improved generate emtests and generate spectests --- Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5eb9c9aa23e..905b5419085 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,14 @@ # Generate files generate-spectests: - WASMER_RUNTIME_GENERATE_SPECTESTS=1 cargo build -p wasmer-runtime-core --release + WASMER_RUNTIME_GENERATE_SPECTESTS=1 cargo build -p wasmer-runtime-core --release \ + && echo "formatting" \ + && cargo fmt generate-emtests: - WASM_EMSCRIPTEN_GENERATE_EMTESTS=1 cargo build -p wasmer-emscripten-tests --release + WASM_EMSCRIPTEN_GENERATE_EMTESTS=1 cargo build -p wasmer-emscripten-tests --release \ + && echo "formatting" \ + && cargo fmt generate-wasitests: wasitests-setup WASM_WASI_GENERATE_WASITESTS=1 cargo build -p wasmer-wasi-tests --release -vv \ From 9942d3ae980df00d87d3813ad3f66aeb5bb1b156 Mon Sep 17 00:00:00 2001 From: Syrus Date: Sun, 22 Sep 2019 18:23:22 -0700 Subject: [PATCH 32/49] Improved Emscripten / WASI autodetection --- lib/emscripten-tests/emtests/issue_577.cpp | 6 ------ lib/emscripten-tests/emtests/issue_577.wasm | Bin 160324 -> 0 bytes lib/emscripten/src/utils.rs | 4 +++- lib/runtime-core/src/structures/map.rs | 4 ++++ lib/wasi/src/utils.rs | 9 ++++++--- src/bin/wasmer.rs | 6 +++--- 6 files changed, 16 insertions(+), 13 deletions(-) delete mode 100644 lib/emscripten-tests/emtests/issue_577.cpp delete mode 100644 lib/emscripten-tests/emtests/issue_577.wasm diff --git a/lib/emscripten-tests/emtests/issue_577.cpp b/lib/emscripten-tests/emtests/issue_577.cpp deleted file mode 100644 index 3b53ca60bbf..00000000000 --- a/lib/emscripten-tests/emtests/issue_577.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main(int argc, char* argv[]) { - std::cout << "Does this work?" << std::endl; - return 0; -} diff --git a/lib/emscripten-tests/emtests/issue_577.wasm b/lib/emscripten-tests/emtests/issue_577.wasm deleted file mode 100644 index 5e3d8ca8a453cde80afa1bf8b189f768129b4b66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160324 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 diff --git a/lib/emscripten/src/utils.rs b/lib/emscripten/src/utils.rs index 2585af43fea..e1c4035653a 100644 --- a/lib/emscripten/src/utils.rs +++ b/lib/emscripten/src/utils.rs @@ -24,7 +24,9 @@ pub fn is_emscripten_module(module: &Module) -> bool { .namespace_table .get(import_name.namespace_index); let field = module.info().name_table.get(import_name.name_index); - if (field == "_emscripten_memcpy_big" || field == "emscripten_memcpy_big") + if (field == "_emscripten_memcpy_big" + || field == "emscripten_memcpy_big" + || field == "__map_file") && namespace == "env" { return true; diff --git a/lib/runtime-core/src/structures/map.rs b/lib/runtime-core/src/structures/map.rs index add5b025785..2d4f3323edd 100644 --- a/lib/runtime-core/src/structures/map.rs +++ b/lib/runtime-core/src/structures/map.rs @@ -39,6 +39,10 @@ where self.elems.len() } + pub fn is_empty(&self) -> bool { + self.elems.is_empty() + } + pub fn push(&mut self, value: V) -> K { let len = self.len(); self.elems.push(value); diff --git a/lib/wasi/src/utils.rs b/lib/wasi/src/utils.rs index 4c3680be2e8..f96e35958df 100644 --- a/lib/wasi/src/utils.rs +++ b/lib/wasi/src/utils.rs @@ -2,14 +2,17 @@ use wasmer_runtime_core::module::Module; /// Check if a provided module is compiled with WASI support pub fn is_wasi_module(module: &Module) -> bool { + if module.info().imported_functions.is_empty() { + return false; + } for (_, import_name) in &module.info().imported_functions { let namespace = module .info() .namespace_table .get(import_name.namespace_index); - if namespace == "wasi_unstable" { - return true; + if namespace != "wasi_unstable" { + return false; } } - false + true } diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index 659f53c715f..b0654495853 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -512,7 +512,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> { import_object.allow_missing_functions = true; // Import initialization might be left to the loader. let instance = module .instantiate(&import_object) - .map_err(|e| format!("Can't instantiate module: {:?}", e))?; + .map_err(|e| format!("Can't instantiate loader module: {:?}", e))?; let args: Vec = options .args @@ -551,7 +551,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> { let import_object = wasmer_emscripten::generate_emscripten_env(&mut emscripten_globals); let mut instance = module .instantiate(&import_object) - .map_err(|e| format!("Can't instantiate module: {:?}", e))?; + .map_err(|e| format!("Can't instantiate emscripten module: {:?}", e))?; wasmer_emscripten::run_emscripten_instance( &module, @@ -591,7 +591,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> { #[allow(unused_mut)] // mut used in feature let mut instance = module .instantiate(&import_object) - .map_err(|e| format!("Can't instantiate module: {:?}", e))?; + .map_err(|e| format!("Can't instantiate WASI module: {:?}", e))?; let start: Func<(), ()> = instance.func("_start").map_err(|e| format!("{:?}", e))?; From 88b2bbc44fba21697a082552b79844c606f4c10e Mon Sep 17 00:00:00 2001 From: Syrus Date: Sun, 22 Sep 2019 18:29:13 -0700 Subject: [PATCH 33/49] Improved error message --- src/bin/wasmer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index b0654495853..a46d3f059e9 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -752,7 +752,7 @@ fn run(options: Run) { match execute_wasm(&options) { Ok(()) => {} Err(message) => { - eprintln!("execute_wasm: {:?}", message); + eprintln!("Error while running the WebAssembly Module: {}", message); exit(1); } } From e99119ace6ea2f9df3403fdd1ba75882db18846b Mon Sep 17 00:00:00 2001 From: Syrus Date: Sun, 22 Sep 2019 18:32:39 -0700 Subject: [PATCH 34/49] Added changes in CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14f7480991d..454f2f28760 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Blocks of changes will separated by version increments. ## **[Unreleased]** +- [#823](https://github.com/wasmerio/wasmer/issues/823) Improved Emscripten / WASI integration - [#821](https://github.com/wasmerio/wasmer/issues/821) Remove patch version on most deps Cargo manifests. This gives Wasmer library users more control over which versions of the deps they use. - [#820](https://github.com/wasmerio/wasmer/issues/820) Remove null-pointer checks in `WasmPtr` from runtime-core, re-add them in Emscripten - [#803](https://github.com/wasmerio/wasmer/issues/803) Add method to `Ctx` to invoke functions by their `TableIndex` From 62f76b1d5e57e22f87b02be70074a4640ced0266 Mon Sep 17 00:00:00 2001 From: Syrus Date: Sun, 22 Sep 2019 18:35:26 -0700 Subject: [PATCH 35/49] Simplified error message --- src/bin/wasmer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index a46d3f059e9..cbbea3b6b64 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -752,7 +752,7 @@ fn run(options: Run) { match execute_wasm(&options) { Ok(()) => {} Err(message) => { - eprintln!("Error while running the WebAssembly Module: {}", message); + eprintln!("Error: {}", message); exit(1); } } From 5ace7a0af3f0cb1b5e91164b41b8c2ecb3f4d0b1 Mon Sep 17 00:00:00 2001 From: Patrick Ventuzelo Date: Mon, 23 Sep 2019 11:17:02 +0200 Subject: [PATCH 36/49] fix failing test --- lib/runtime-core/src/memory/mod.rs | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/lib/runtime-core/src/memory/mod.rs b/lib/runtime-core/src/memory/mod.rs index bc82d2f822c..e78c6af84c7 100644 --- a/lib/runtime-core/src/memory/mod.rs +++ b/lib/runtime-core/src/memory/mod.rs @@ -53,16 +53,12 @@ impl Memory { /// # use wasmer_runtime_core::memory::Memory; /// # use wasmer_runtime_core::error::Result; /// # use wasmer_runtime_core::units::Pages; - /// # fn create_memory() -> Result<()> { - /// let descriptor = MemoryDescriptor { - /// minimum: Pages(10), - /// maximum: None, - /// shared: false, - /// }; + /// fn create_memory() -> Result<()> { + /// let descriptor = MemoryDescriptor::new(Pages(10), None, false).unwrap(); /// - /// let memory = Memory::new(descriptor)?; - /// # Ok(()) - /// # } + /// let memory = Memory::new(descriptor)?; + /// Ok(()) + /// } /// ``` pub fn new(desc: MemoryDescriptor) -> Result { if let Some(max) = desc.maximum { @@ -346,24 +342,16 @@ mod memory_tests { #[test] fn test_initial_memory_size() { - let unshared_memory = Memory::new(MemoryDescriptor { - minimum: Pages(10), - maximum: Some(Pages(20)), - shared: false, - }) - .unwrap(); + let memory_desc = MemoryDescriptor::new(Pages(10), Some(Pages(20)), false).unwrap(); + let unshared_memory = Memory::new(memory_desc).unwrap(); assert_eq!(unshared_memory.size(), Pages(10)); } #[test] fn test_invalid_descriptor_returns_error() { - let result = Memory::new(MemoryDescriptor { - minimum: Pages(10), - maximum: None, - shared: true, - }); + let memory_desc = MemoryDescriptor::new(Pages(10), None, true); assert!( - result.is_err(), + memory_desc.is_err(), "Max number of pages is required for shared memory" ) } From f289cb2ba99877a475d6aa57eec3b2a474e425e2 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 23 Sep 2019 15:15:06 +0200 Subject: [PATCH 37/49] doc(runtime-core) Replace `map(|cell| cell.get())` by `map(Cell::get)`. Because it's simpler :-p. --- lib/runtime-core/src/memory/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/runtime-core/src/memory/mod.rs b/lib/runtime-core/src/memory/mod.rs index 75e9ea007dc..7236855ad81 100644 --- a/lib/runtime-core/src/memory/mod.rs +++ b/lib/runtime-core/src/memory/mod.rs @@ -131,11 +131,11 @@ impl Memory { /// /// ``` /// # use wasmer_runtime_core::memory::{Memory, MemoryView}; - /// # use std::sync::atomic::Ordering; + /// # use std::{cell::Cell, sync::atomic::Ordering}; /// # fn view_memory(memory: Memory) { /// // Without synchronization. /// let view: MemoryView = memory.view(); - /// for byte in view[0x1000 .. 0x1010].iter().map(|cell| cell.get()) { + /// for byte in view[0x1000 .. 0x1010].iter().map(Cell::get) { /// println!("byte: {}", byte); /// } /// From 2ef64b0a19b2f1637a0fcd90355e6561f545daea Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Mon, 23 Sep 2019 10:20:46 -0700 Subject: [PATCH 38/49] Update feature matrix with input from Brandon and Nick --- docs/feature_matrix.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/feature_matrix.md b/docs/feature_matrix.md index abca531d6d2..6931c38b4d4 100644 --- a/docs/feature_matrix.md +++ b/docs/feature_matrix.md @@ -5,9 +5,12 @@ |   | Singlepass | Cranelift | LLVM | | - | - | - | - | | Caching | ❌ | ✅ | ✅ | -| SIMD | ❌ | ❌ | ✅ | +| Emscripten | ✅ | ✅ | ✅ | +| Metering | ✅ | ❌ | ✅ | | Multi-value return | ❌ | ❌ | ❌ | -| Metering | ✅ | ✅ | ❓ | +| OSR | 🚧 | ❓ | ❓ | +| SIMD | ❌ | ❌ | ✅ | +| WASI | ✅ | ✅ | ✅ | ## Language integration From 05ad1aaea4c8d259ef10e334e70ddb53dca4e17d Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Mon, 23 Sep 2019 11:04:31 -0700 Subject: [PATCH 39/49] Add test for Instance, fix tests for ImportObject --- CHANGELOG.md | 1 + lib/runtime-core/src/import.rs | 30 ++++++++++++++++-------------- lib/runtime-core/src/instance.rs | 12 ++++++++++++ 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1651f7ffbeb..caa92879209 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Blocks of changes will separated by version increments. ## **[Unreleased]** +- [#807](https://github.com/wasmerio/wasmer/pull/807) Implement Send for `Instance`, breaking change on `ImportObject`, remove method `get_namespace` replaced with `with_namespace` and `maybe_with_namespace` - [#790](https://github.com/wasmerio/wasmer/pull/790) Fix flaky test failure with LLVM, switch to large code model. - [#788](https://github.com/wasmerio/wasmer/pull/788) Use union merge on the changelog file. - [#785](https://github.com/wasmerio/wasmer/pull/785) Include Apache license file for spectests. diff --git a/lib/runtime-core/src/import.rs b/lib/runtime-core/src/import.rs index ff09450feb1..2cccf2325af 100644 --- a/lib/runtime-core/src/import.rs +++ b/lib/runtime-core/src/import.rs @@ -266,12 +266,14 @@ mod test { imports1.extend(imports2); - let cat_ns = imports1.get_namespace("cat").unwrap(); - assert!(cat_ns.get_export("small").is_some()); - - let dog_ns = imports1.get_namespace("dog").unwrap(); - assert!(dog_ns.get_export("happy").is_some()); - assert!(dog_ns.get_export("small").is_some()); + let small_cat_export = + imports1.maybe_with_namespace("cat", |cat_ns| cat_ns.get_export("small")); + assert!(small_cat_export.is_some()); + + let entries = imports1.maybe_with_namespace("dog", |dog_ns| { + Some((dog_ns.get_export("happy")?, dog_ns.get_export("small")?)) + }); + assert!(entries.is_some()); } #[test] @@ -289,14 +291,14 @@ mod test { }; imports1.extend(imports2); - let dog_ns = imports1.get_namespace("dog").unwrap(); + let happy_dog_entry = imports1 + .maybe_with_namespace("dog", |dog_ns| dog_ns.get_export("happy")) + .unwrap(); - assert!( - if let Export::Global(happy_dog_global) = dog_ns.get_export("happy").unwrap() { - happy_dog_global.get() == Value::I32(4) - } else { - false - } - ); + assert!(if let Export::Global(happy_dog_global) = happy_dog_entry { + happy_dog_global.get() == Value::I32(4) + } else { + false + }); } } diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index 6f30b0a7489..c6867d1005e 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -752,3 +752,15 @@ impl<'a> DynFunc<'a> { } } } + +#[cfg(test)] +mod test { + use super::*; + + fn is_send() {} + + #[test] + fn test_instance_is_send() { + is_send::(); + } +} From c4818f12dc7a6c031eaf5f5f868b4abb26156c99 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Mon, 23 Sep 2019 13:43:01 -0700 Subject: [PATCH 40/49] Update spectests to work with new Instance; use Arc> --- lib/runtime-core/src/instance.rs | 28 +++- lib/spectests/tests/spectest.rs | 223 +++++++++++++------------------ 2 files changed, 121 insertions(+), 130 deletions(-) diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index 9ffd0577ebd..85e9f8f768b 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -16,7 +16,12 @@ use crate::{ vm::{self, InternalField}, }; use smallvec::{smallvec, SmallVec}; -use std::{mem, pin::Pin, ptr::NonNull, sync::Arc}; +use std::{ + mem, + pin::Pin, + ptr::NonNull, + sync::{Arc, Mutex}, +}; pub(crate) struct InstanceInner { #[allow(dead_code)] @@ -520,6 +525,27 @@ impl LikeNamespace for Rc { } } +impl LikeNamespace for Arc> { + fn get_export(&self, name: &str) -> Option { + let instance = self.lock().unwrap(); + let export_index = instance.module.info.exports.get(name)?; + + Some( + instance + .inner + .get_export_from_index(&instance.module, export_index), + ) + } + + fn get_exports(&self) -> Vec<(String, Export)> { + unimplemented!("Use the exports method instead"); + } + + fn maybe_insert(&mut self, _name: &str, _export: Export) -> Option<()> { + None + } +} + #[must_use] fn call_func_with_index( info: &ModuleInfo, diff --git a/lib/spectests/tests/spectest.rs b/lib/spectests/tests/spectest.rs index 9cd18d636a8..66a730d7650 100644 --- a/lib/spectests/tests/spectest.rs +++ b/lib/spectests/tests/spectest.rs @@ -18,7 +18,7 @@ mod tests { // TODO Files could be run with multiple threads // TODO Allow running WAST &str directly (E.g. for use outside of spectests) - use std::rc::Rc; + use std::sync::{Arc, Mutex}; struct SpecFailure { file: String, @@ -119,6 +119,24 @@ mod tests { "unknown" } + fn with_instance( + maybe_instance: Option>>, + named_modules: &HashMap>>, + module: &Option, + f: F, + ) -> Option + where + R: Sized, + F: FnOnce(&Instance) -> R, + { + let ref ins = module + .as_ref() + .and_then(|name| named_modules.get(name).cloned()) + .or(maybe_instance)?; + let guard = ins.lock().unwrap(); + Some(f(guard.borrow())) + } + use glob::glob; use std::collections::HashMap; use std::fs; @@ -173,11 +191,11 @@ mod tests { .expect(&format!("Failed to parse script {}", &filename)); use std::panic; - let mut instance: Option> = None; + let mut instance: Option>> = None; - let mut named_modules: HashMap> = HashMap::new(); + let mut named_modules: HashMap>> = HashMap::new(); - let mut registered_modules: HashMap> = HashMap::new(); + let mut registered_modules: HashMap>> = HashMap::new(); // while let Some(Command { kind, line }) = @@ -236,9 +254,9 @@ mod tests { instance = None; } Ok(i) => { - let i = Rc::new(i); + let i = Arc::new(Mutex::new(i)); if name.is_some() { - named_modules.insert(name.unwrap(), Rc::clone(&i)); + named_modules.insert(name.unwrap(), Arc::clone(&i)); } instance = Some(i); } @@ -251,20 +269,17 @@ mod tests { field, args, } => { - let instance: Option<&Instance> = match module { - Some(ref name) => { - let i = named_modules.get(name); - match i { - Some(ins) => Some(ins.borrow()), - None => None, - } - } - None => match instance { - Some(ref i) => Some(i.borrow()), - None => None, + let maybe_call_result = with_instance( + instance.clone(), + &named_modules, + &module, + |instance| { + let params: Vec = + args.iter().cloned().map(convert_value).collect(); + instance.call(&field, ¶ms[..]) }, - }; - if instance.is_none() { + ); + if maybe_call_result.is_none() { test_report.add_failure( SpecFailure { file: filename.to_string(), @@ -276,9 +291,7 @@ mod tests { excludes, ); } else { - let params: Vec = - args.iter().cloned().map(|x| convert_value(x)).collect(); - let call_result = instance.unwrap().call(&field, ¶ms[..]); + let call_result = maybe_call_result.unwrap(); match call_result { Err(e) => { test_report.add_failure( @@ -316,20 +329,17 @@ mod tests { } } Action::Get { module, field } => { - let instance: Option<&Instance> = match module { - Some(ref name) => { - let i = named_modules.get(name); - match i { - Some(ins) => Some(ins.borrow()), - None => None, - } - } - None => match instance { - Some(ref i) => Some(i.borrow()), - None => None, + let maybe_call_result = with_instance( + instance.clone(), + &named_modules, + &module, + |instance| { + instance + .get_export(&field) + .expect(&format!("missing global {:?}", &field)) }, - }; - if instance.is_none() { + ); + if maybe_call_result.is_none() { test_report.add_failure( SpecFailure { file: filename.to_string(), @@ -341,10 +351,7 @@ mod tests { excludes, ); } else { - let export: Export = instance - .unwrap() - .get_export(&field) - .expect(&format!("missing global {:?}", &field)); + let export: Export = maybe_call_result.unwrap(); match export { Export::Global(g) => { let value = g.get(); @@ -392,20 +399,13 @@ mod tests { field, args, } => { - let instance: Option<&Instance> = match module { - Some(ref name) => { - let i = named_modules.get(name); - match i { - Some(ins) => Some(ins.borrow()), - None => None, - } - } - None => match instance { - Some(ref i) => Some(i.borrow()), - None => None, - }, - }; - if instance.is_none() { + let maybe_call_result = + with_instance(instance.clone(), &named_modules, &module, |instance| { + let params: Vec = + args.iter().cloned().map(convert_value).collect(); + instance.call(&field, ¶ms[..]) + }); + if maybe_call_result.is_none() { test_report.add_failure( SpecFailure { file: filename.to_string(), @@ -417,9 +417,7 @@ mod tests { excludes, ); } else { - let params: Vec = - args.iter().cloned().map(|x| convert_value(x)).collect(); - let call_result = instance.unwrap().call(&field, ¶ms[..]); + let call_result = maybe_call_result.unwrap(); match call_result { Err(e) => { test_report.add_failure( @@ -468,20 +466,13 @@ mod tests { field, args, } => { - let instance: Option<&Instance> = match module { - Some(ref name) => { - let i = named_modules.get(name); - match i { - Some(ins) => Some(ins.borrow()), - None => None, - } - } - None => match instance { - Some(ref i) => Some(i.borrow()), - None => None, - }, - }; - if instance.is_none() { + let maybe_call_result = + with_instance(instance.clone(), &named_modules, &module, |instance| { + let params: Vec = + args.iter().cloned().map(convert_value).collect(); + instance.call(&field, ¶ms[..]) + }); + if maybe_call_result.is_none() { test_report.add_failure( SpecFailure { file: filename.to_string(), @@ -493,9 +484,7 @@ mod tests { excludes, ); } else { - let params: Vec = - args.iter().cloned().map(|x| convert_value(x)).collect(); - let call_result = instance.unwrap().call(&field, ¶ms[..]); + let call_result = maybe_call_result.unwrap(); match call_result { Err(e) => { test_report.add_failure( @@ -544,20 +533,13 @@ mod tests { field, args, } => { - let instance: Option<&Instance> = match module { - Some(ref name) => { - let i = named_modules.get(name); - match i { - Some(ins) => Some(ins.borrow()), - None => None, - } - } - None => match instance { - Some(ref i) => Some(i.borrow()), - None => None, - }, - }; - if instance.is_none() { + let maybe_call_result = + with_instance(instance.clone(), &named_modules, &module, |instance| { + let params: Vec = + args.iter().cloned().map(convert_value).collect(); + instance.call(&field, ¶ms[..]) + }); + if maybe_call_result.is_none() { test_report.add_failure( SpecFailure { file: filename.to_string(), @@ -569,9 +551,7 @@ mod tests { excludes, ); } else { - let params: Vec = - args.iter().cloned().map(|x| convert_value(x)).collect(); - let call_result = instance.unwrap().call(&field, ¶ms[..]); + let call_result = maybe_call_result.unwrap(); use wasmer_runtime_core::error::{CallError, RuntimeError}; match call_result { Err(e) => { @@ -749,20 +729,17 @@ mod tests { field, args, } => { - let instance: Option<&Instance> = match module { - Some(ref name) => { - let i = named_modules.get(name); - match i { - Some(ins) => Some(ins.borrow()), - None => None, - } - } - None => match instance { - Some(ref i) => Some(i.borrow()), - None => None, + let maybe_call_result = with_instance( + instance.clone(), + &named_modules, + &module, + |instance| { + let params: Vec = + args.iter().cloned().map(convert_value).collect(); + instance.call(&field, ¶ms[..]) }, - }; - if instance.is_none() { + ); + if maybe_call_result.is_none() { test_report.add_failure( SpecFailure { file: filename.to_string(), @@ -774,9 +751,7 @@ mod tests { excludes, ); } else { - let params: Vec = - args.iter().cloned().map(|x| convert_value(x)).collect(); - let call_result = instance.unwrap().call(&field, ¶ms[..]); + let call_result = maybe_call_result.unwrap(); match call_result { Err(_e) => { // TODO is specific error required? @@ -871,16 +846,16 @@ mod tests { } } CommandKind::Register { name, as_name } => { - let instance: Option> = match name { + let instance: Option>> = match name { Some(ref name) => { let i = named_modules.get(name); match i { - Some(ins) => Some(Rc::clone(ins)), + Some(ins) => Some(Arc::clone(ins)), None => None, } } None => match instance { - Some(ref i) => Some(Rc::clone(i)), + Some(ref i) => Some(Arc::clone(i)), None => None, }, }; @@ -906,21 +881,13 @@ mod tests { field, args, } => { - let instance: Option<&Instance> = match module { - Some(ref name) => { - let i = named_modules.get(name); - match i { - Some(ins) => Some(ins.borrow()), - None => None, - } - } - None => match instance { - Some(ref i) => Some(i.borrow()), - None => None, - }, - }; - - if instance.is_none() { + let maybe_call_result = + with_instance(instance.clone(), &named_modules, &module, |instance| { + let params: Vec = + args.iter().cloned().map(convert_value).collect(); + instance.call(&field, ¶ms[..]) + }); + if maybe_call_result.is_none() { test_report.add_failure( SpecFailure { file: filename.to_string(), @@ -932,9 +899,7 @@ mod tests { excludes, ); } else { - let params: Vec = - args.iter().cloned().map(|x| convert_value(x)).collect(); - let call_result = instance.unwrap().call(&field, ¶ms[..]); + let call_result = maybe_call_result.unwrap(); match call_result { Err(e) => { test_report.add_failure( @@ -1054,7 +1019,7 @@ mod tests { } fn get_spectest_import_object( - registered_modules: &HashMap>, + registered_modules: &HashMap>>, ) -> ImportObject { let memory = Memory::new(MemoryDescriptor { minimum: Pages(1), @@ -1091,7 +1056,7 @@ mod tests { }; for (name, instance) in registered_modules.iter() { - import_object.register(name.clone(), Rc::clone(instance)); + import_object.register(name.clone(), Arc::clone(instance)); } import_object } From ebb7618341b9bd39c8726ec9a0d80bcd749052ba Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2019 21:48:18 +0000 Subject: [PATCH 41/49] Bump serde_derive from 1.0.100 to 1.0.101 Bumps [serde_derive](https://github.com/serde-rs/serde) from 1.0.100 to 1.0.101. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.100...v1.0.101) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3d8c85a48c9..44934a87b45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,7 +157,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -310,7 +310,7 @@ dependencies = [ "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1132,7 +1132,7 @@ name = "serde" version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1154,7 +1154,7 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.100" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1422,7 +1422,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1493,7 +1493,7 @@ dependencies = [ "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-clif-fork-frontend 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-clif-fork-wasm 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1656,7 +1656,7 @@ dependencies = [ "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "wasmparser 0.35.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1926,7 +1926,7 @@ dependencies = [ "checksum serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)" = "f4473e8506b213730ff2061073b48fa51dcc66349219e2e7c5608f0296a1d95a" "checksum serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d733da87e79faaac25616e33d26299a41143fd4cd42746cbb0e91d8feea243fd" "checksum serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "45af0182ff64abaeea290235eb67da3825a576c5d53e642c4d5b652e12e6effc" -"checksum serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)" = "11e410fde43e157d789fc290d26bc940778ad0fdd47836426fbac36573710dbb" +"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" "checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" From 2af031148777f688cde9c5bc7fac42c0664698a5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2019 22:13:04 +0000 Subject: [PATCH 42/49] Bump serde from 1.0.100 to 1.0.101 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.100 to 1.0.101. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.100...v1.0.101) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 44934a87b45..095bec64b9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,7 +70,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -118,7 +118,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -156,7 +156,7 @@ name = "cargo_toml" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -175,7 +175,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -309,7 +309,7 @@ dependencies = [ "rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -374,7 +374,7 @@ dependencies = [ "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -457,7 +457,7 @@ name = "erased-serde" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -528,7 +528,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -605,7 +605,7 @@ name = "indexmap" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1129,7 +1129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.100" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1141,7 +1141,7 @@ version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1149,7 +1149,7 @@ name = "serde_bytes" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1169,7 +1169,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1329,7 +1329,7 @@ name = "tinytemplate" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1338,7 +1338,7 @@ name = "toml" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1346,7 +1346,7 @@ name = "toml" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1362,7 +1362,7 @@ dependencies = [ "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "inventory 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "typetag-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1421,7 +1421,7 @@ name = "wabt" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1460,7 +1460,7 @@ dependencies = [ "errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1490,7 +1490,7 @@ dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1653,7 +1653,7 @@ dependencies = [ "page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1699,7 +1699,7 @@ dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.7.0", @@ -1923,7 +1923,7 @@ dependencies = [ "checksum scroll_derive 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1aa96c45e7f5a91cb7fabe7b279f02fea7126239fc40b732316e8b6a2d0fcb" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)" = "f4473e8506b213730ff2061073b48fa51dcc66349219e2e7c5608f0296a1d95a" +"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" "checksum serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d733da87e79faaac25616e33d26299a41143fd4cd42746cbb0e91d8feea243fd" "checksum serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "45af0182ff64abaeea290235eb67da3825a576c5d53e642c4d5b652e12e6effc" "checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" From 5fde93dcbd34c349597b1fc21290df25569dd98a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2019 22:32:22 +0000 Subject: [PATCH 43/49] Bump structopt from 0.3.1 to 0.3.2 Bumps [structopt](https://github.com/TeXitoi/structopt) from 0.3.1 to 0.3.2. - [Release notes](https://github.com/TeXitoi/structopt/releases) - [Changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) - [Commits](https://github.com/TeXitoi/structopt/compare/v0.3.1...v0.3.2) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 095bec64b9d..223ef76ac40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1194,16 +1194,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "structopt" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "structopt-derive" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1461,7 +1461,7 @@ dependencies = [ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-clif-backend 0.7.0", @@ -1932,8 +1932,8 @@ dependencies = [ "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -"checksum structopt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ac9d6e93dd792b217bf89cda5c14566e3043960c6f9da890c2ba5d09d07804c" -"checksum structopt-derive 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ae9e5165d463a0dea76967d021f8d0f9316057bf5163aa2a4843790e842ff37" +"checksum structopt 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe8d3289b63ef2f196d89e7701f986583c0895e764b78f052a55b9b5d34d84a" +"checksum structopt-derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f3add731f5b4fb85931d362a3c92deb1ad7113649a8d51701fb257673705f122" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" From 91cd88fde60582e180259d6b7a50b5a9799476d3 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Mon, 23 Sep 2019 16:33:29 -0700 Subject: [PATCH 44/49] Fix bench targets in makefile --- Makefile | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 905b5419085..89210b9b046 100644 --- a/Makefile +++ b/Makefile @@ -140,11 +140,15 @@ install: # Checks check-bench-singlepass: - cargo bench --all --no-run --no-default-features --features "backend-singlepass" + cargo bench --all --no-run --no-default-features --features "backend-singlepass" \ + --exclude wasmer-clif-backend --exclude wasmer-llvm-backend --exclude wasmer-kernel-loader check-bench-clif: - cargo bench --all --no-run --no-default-features --features "backend-cranelift" + cargo bench --all --no-run --no-default-features --features "backend-cranelift" \ + --exclude wasmer-singlepass-backend --exclude wasmer-llvm-backend --exclude wasmer-kernel-loader \ + --exclude wasmer-middleware-common-tests check-bench-llvm: - cargo bench --all --no-run --no-default-features --features "backend-llvm" + cargo bench --all --no-run --no-default-features --features "backend-llvm" \ + --exclude wasmer-singlepass-backend --exclude wasmer-clif-backend --exclude wasmer-kernel-loader check-bench: check-bench-singlepass check-bench-llvm @@ -168,11 +172,15 @@ release-llvm: cargo build --release --features backend-llvm bench-singlepass: - cargo bench --all --no-default-features --features "backend-singlepass" + cargo bench --all --no-default-features --features "backend-singlepass" \ + --exclude wasmer-clif-backend --exclude wasmer-llvm-backend --exclude wasmer-kernel-loader bench-clif: - cargo bench --all --no-default-features --features "backend-cranelift" + cargo bench --all --no-default-features --features "backend-cranelift" \ + --exclude wasmer-singlepass-backend --exclude wasmer-llvm-backend --exclude wasmer-kernel-loader \ + --exclude wasmer-middleware-common-tests bench-llvm: - cargo bench --all --no-default-features --features "backend-llvm" + cargo bench --all --no-default-features --features "backend-llvm" \ + --exclude wasmer-singlepass-backend --exclude wasmer-clif-backend --exclude wasmer-kernel-loader # Build utils build-install: From 57b8947d6adaf1be85c961a6ed360e0e67867b7c Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Mon, 23 Sep 2019 16:53:53 -0700 Subject: [PATCH 45/49] Add bench fix to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20432fe832c..d42122a61a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Blocks of changes will separated by version increments. ## **[Unreleased]** +- [#829](https://github.com/wasmerio/wasmer/pull/829) Fix deps on `make bench-*` commands; benchmarks don't compile other backends now - [#807](https://github.com/wasmerio/wasmer/pull/807) Implement Send for `Instance`, breaking change on `ImportObject`, remove method `get_namespace` replaced with `with_namespace` and `maybe_with_namespace` - [#817](https://github.com/wasmerio/wasmer/pull/817) Add document for tracking features across backends and language integrations, [docs/feature_matrix.md] - [#823](https://github.com/wasmerio/wasmer/issues/823) Improved Emscripten / WASI integration From 79ff3709ccd6cf4c890c0d1b2ccf96c0e0c5b749 Mon Sep 17 00:00:00 2001 From: Patrick Ventuzelo Date: Tue, 24 Sep 2019 09:08:55 +0200 Subject: [PATCH 46/49] fix cargo check fail build --- lib/runtime-c-api/src/memory.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/runtime-c-api/src/memory.rs b/lib/runtime-c-api/src/memory.rs index 4628d8baa15..21f14bbf77c 100644 --- a/lib/runtime-c-api/src/memory.rs +++ b/lib/runtime-c-api/src/memory.rs @@ -1,6 +1,6 @@ //! Create, read, write, grow, destroy memory of an instance. -use crate::{error::update_last_error, wasmer_limits_t, wasmer_result_t}; +use crate::{error::update_last_error, error::CApiError, wasmer_limits_t, wasmer_result_t}; use std::cell::Cell; use wasmer_runtime::Memory; use wasmer_runtime_core::{ @@ -31,12 +31,17 @@ pub unsafe extern "C" fn wasmer_memory_new( } else { None }; - let desc = MemoryDescriptor { - minimum: Pages(limits.min), - maximum: max, - shared: false, + let desc = MemoryDescriptor::new(Pages(limits.min), max, false); + let new_desc = match desc { + Ok(desc) => desc, + Err(error) => { + update_last_error(CApiError { + msg: error.to_string(), + }); + return wasmer_result_t::WASMER_ERROR; + } }; - let result = Memory::new(desc); + let result = Memory::new(new_desc); let new_memory = match result { Ok(memory) => memory, Err(error) => { From b6d55b0b85c4a7f53d80fb892b42f4759d48fd29 Mon Sep 17 00:00:00 2001 From: Brandon Fish Date: Tue, 24 Sep 2019 13:30:52 -0500 Subject: [PATCH 47/49] Update to published fork version --- Cargo.lock | 96 ++++++++++++++++++------------------- lib/clif-backend/Cargo.toml | 10 ++-- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3270ab2f7ea..dfba92b46c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -248,19 +248,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cranelift-bforest" version = "0.43.1" -source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cranelift-entity 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-entity 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cranelift-codegen" version = "0.43.1" -source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cranelift-bforest 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", - "cranelift-codegen-meta 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", - "cranelift-entity 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-bforest 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-codegen-meta 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-entity 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -271,51 +271,26 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" version = "0.43.1" -source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cranelift-entity 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-entity 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cranelift-entity" version = "0.43.1" -source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" - -[[package]] -name = "cranelift-frontend" -version = "0.43.1" -source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" -dependencies = [ - "cranelift-codegen 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", -] +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cranelift-native" version = "0.43.1" -source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cranelift-codegen 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-codegen 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", "raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cranelift-wasm" -version = "0.43.1" -source = "git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1#c5da7629c0dabcafb083efb5f9b8db39c20a4dc4" -dependencies = [ - "cranelift-codegen 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", - "cranelift-entity 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", - "cranelift-frontend 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmparser 0.37.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "criterion" version = "0.2.11" @@ -1510,11 +1485,9 @@ name = "wasmer-clif-backend" version = "0.7.0" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-codegen 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", - "cranelift-entity 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", - "cranelift-frontend 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", - "cranelift-native 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", - "cranelift-wasm 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)", + "cranelift-codegen 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-entity 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-native 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1523,12 +1496,39 @@ dependencies = [ "serde_bytes 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-clif-fork-frontend 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-clif-fork-wasm 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.7.0", "wasmer-win-exception-handler 0.7.0", "wasmparser 0.37.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "wasmer-clif-fork-frontend" +version = "0.43.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cranelift-codegen 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "target-lexicon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasmer-clif-fork-wasm" +version = "0.43.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cranelift-codegen 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-entity 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-clif-fork-frontend 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmparser 0.37.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "wasmer-dev-utils" version = "0.7.0" @@ -1823,13 +1823,11 @@ dependencies = [ "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" "checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" -"checksum cranelift-bforest 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" -"checksum cranelift-codegen 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" -"checksum cranelift-codegen-meta 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" -"checksum cranelift-entity 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" -"checksum cranelift-frontend 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" -"checksum cranelift-native 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" -"checksum cranelift-wasm 0.43.1 (git+https://github.com/wasmerio/cranelift?branch=feature/merge-cranelift-0-43-1)" = "" +"checksum cranelift-bforest 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ed78b27612fb7dc10877dfae16a5c36fc4a9384729116d06c987c780fda11cc3" +"checksum cranelift-codegen 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)" = "df961b45555487ca468768ce4e00a7201a57dccc12fa04abaaf1759377341e9c" +"checksum cranelift-codegen-meta 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a65acf11ac45463e2469e1e85a6ea5f4629e1805c7881e4b5790b5bfead28c1" +"checksum cranelift-entity 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9809b6af0562dfba216ccee8a6dde11f4f2d3c13dabb20204d0a17114605b8" +"checksum cranelift-native 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a68c68c1eed53405d06d58551d7f27feadbf6e2d3a92bec24b4ef6b47b5b6fd" "checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394" "checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" @@ -1968,6 +1966,8 @@ dependencies = [ "checksum wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af5d153dc96aad7dc13ab90835b892c69867948112d95299e522d370c4e13a08" "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +"checksum wasmer-clif-fork-frontend 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)" = "360702a9773968dec6ec8e85446810376565b57fed51d41ebcc43862bd4a57f1" +"checksum wasmer-clif-fork-wasm 0.43.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ecf72cbea9ec1f56270cb849816e31c24abb2b9c9d3348aa1244d735910d849d" "checksum wasmparser 0.37.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7387ba67c13dd9cd01d7d961e733375aee889f828564e190da85b5602eb5eeb" "checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/lib/clif-backend/Cargo.toml b/lib/clif-backend/Cargo.toml index 3aa7f735e86..37b3c714407 100644 --- a/lib/clif-backend/Cargo.toml +++ b/lib/clif-backend/Cargo.toml @@ -10,11 +10,11 @@ readme = "README.md" [dependencies] wasmer-runtime-core = { path = "../runtime-core", version = "0.7.0" } -cranelift-native = { git = "https://github.com/wasmerio/cranelift", branch = "feature/merge-cranelift-0-43-1" } -cranelift-codegen = { git = "https://github.com/wasmerio/cranelift", branch = "feature/merge-cranelift-0-43-1" } -cranelift-entity = { git = "https://github.com/wasmerio/cranelift", branch = "feature/merge-cranelift-0-43-1" } -cranelift-frontend = { git = "https://github.com/wasmerio/cranelift", branch = "feature/merge-cranelift-0-43-1" } -cranelift-wasm = { git = "https://github.com/wasmerio/cranelift", branch = "feature/merge-cranelift-0-43-1" } +cranelift-native = "0.43.1" +cranelift-codegen = "0.43.1" +cranelift-entity = "0.43.1" +cranelift-frontend = { package = "wasmer-clif-fork-frontend", version = "0.43.1" } +cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.43.1" } target-lexicon = "0.8.1" wasmparser = "0.37.0" byteorder = "1.3.2" From 621ef56ab6c2a4b3e3a0d4bee257cb95a1c5d004 Mon Sep 17 00:00:00 2001 From: Syrus Date: Tue, 24 Sep 2019 13:36:31 -0700 Subject: [PATCH 48/49] lmproved READMEs to use Azure Pipelines badges and better lgo --- lib/clif-backend/README.md | 8 ++++---- lib/llvm-backend/README.md | 8 ++++---- lib/runtime-c-api/README.md | 8 ++++---- lib/runtime-core/README.md | 8 ++++---- lib/runtime/README.md | 8 ++++---- lib/singlepass-backend/README.md | 8 ++++---- lib/spectests/README.md | 8 ++++---- lib/win-exception-handler/README.md | 8 ++++---- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/lib/clif-backend/README.md b/lib/clif-backend/README.md index 2f29f4543ba..e81f4666529 100644 --- a/lib/clif-backend/README.md +++ b/lib/clif-backend/README.md @@ -1,15 +1,15 @@

- Wasmer logo + Wasmer logo

- - Build Status + + Build Status - License + License Join the Wasmer Community diff --git a/lib/llvm-backend/README.md b/lib/llvm-backend/README.md index 08dc5c5d9dd..ec3c43a77fb 100644 --- a/lib/llvm-backend/README.md +++ b/lib/llvm-backend/README.md @@ -1,15 +1,15 @@

- Wasmer logo + Wasmer logo

- - Build Status + + Build Status - License + License Join the Wasmer Community diff --git a/lib/runtime-c-api/README.md b/lib/runtime-c-api/README.md index 1e741cfd121..4fefa6d764a 100644 --- a/lib/runtime-c-api/README.md +++ b/lib/runtime-c-api/README.md @@ -1,15 +1,15 @@

- Wasmer logo + Wasmer logo

- - Build Status + + Build Status - License + License Join the Wasmer Community diff --git a/lib/runtime-core/README.md b/lib/runtime-core/README.md index 0bbb74379d3..0c4e784e784 100644 --- a/lib/runtime-core/README.md +++ b/lib/runtime-core/README.md @@ -1,15 +1,15 @@

- Wasmer logo + Wasmer logo

- - Build Status + + Build Status - License + License Join the Wasmer Community diff --git a/lib/runtime/README.md b/lib/runtime/README.md index cbb6388aaab..68763f32890 100644 --- a/lib/runtime/README.md +++ b/lib/runtime/README.md @@ -1,15 +1,15 @@

- Wasmer logo + Wasmer logo

- - Build Status + + Build Status - License + License Join the Wasmer Community diff --git a/lib/singlepass-backend/README.md b/lib/singlepass-backend/README.md index bf477a3388b..e63e6f1b661 100644 --- a/lib/singlepass-backend/README.md +++ b/lib/singlepass-backend/README.md @@ -1,15 +1,15 @@

- Wasmer logo + Wasmer logo

- - Build Status + + Build Status - License + License Join the Wasmer Community diff --git a/lib/spectests/README.md b/lib/spectests/README.md index 439b95887b0..0d3c248e04b 100644 --- a/lib/spectests/README.md +++ b/lib/spectests/README.md @@ -1,15 +1,15 @@

- Wasmer logo + Wasmer logo

- - Build Status + + Build Status - License + License Join the Wasmer Community diff --git a/lib/win-exception-handler/README.md b/lib/win-exception-handler/README.md index 9a32e1753bb..351228d04ae 100644 --- a/lib/win-exception-handler/README.md +++ b/lib/win-exception-handler/README.md @@ -1,15 +1,15 @@

- Wasmer logo + Wasmer logo

- - Build Status + + Build Status - License + License Join the Wasmer Community From 7bf306eb277d6ea674d31ad703f47e43a7a466ae Mon Sep 17 00:00:00 2001 From: Syrus Date: Tue, 24 Sep 2019 13:42:17 -0700 Subject: [PATCH 49/49] Use flat-square style in downloads button --- lib/clif-backend/README.md | 2 +- lib/llvm-backend/README.md | 2 +- lib/runtime-c-api/README.md | 2 +- lib/runtime-core/README.md | 2 +- lib/runtime/README.md | 2 +- lib/singlepass-backend/README.md | 2 +- lib/spectests/README.md | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/clif-backend/README.md b/lib/clif-backend/README.md index e81f4666529..7cb3023bf3d 100644 --- a/lib/clif-backend/README.md +++ b/lib/clif-backend/README.md @@ -15,7 +15,7 @@ Join the Wasmer Community - Number of downloads from crates.io + Number of downloads from crates.io Read our API documentation diff --git a/lib/llvm-backend/README.md b/lib/llvm-backend/README.md index ec3c43a77fb..e82396c6170 100644 --- a/lib/llvm-backend/README.md +++ b/lib/llvm-backend/README.md @@ -15,7 +15,7 @@ Join the Wasmer Community - Number of downloads from crates.io + Number of downloads from crates.io Read our API documentation diff --git a/lib/runtime-c-api/README.md b/lib/runtime-c-api/README.md index 4fefa6d764a..4557e0d8ad2 100644 --- a/lib/runtime-c-api/README.md +++ b/lib/runtime-c-api/README.md @@ -15,7 +15,7 @@ Join the Wasmer Community - Number of downloads from crates.io + Number of downloads from crates.io Read our API documentation diff --git a/lib/runtime-core/README.md b/lib/runtime-core/README.md index 0c4e784e784..d64a348bd8d 100644 --- a/lib/runtime-core/README.md +++ b/lib/runtime-core/README.md @@ -15,7 +15,7 @@ Join the Wasmer Community - Number of downloads from crates.io + Number of downloads from crates.io Read our API documentation diff --git a/lib/runtime/README.md b/lib/runtime/README.md index 68763f32890..4f52a5557de 100644 --- a/lib/runtime/README.md +++ b/lib/runtime/README.md @@ -15,7 +15,7 @@ Join the Wasmer Community - Number of downloads from crates.io + Number of downloads from crates.io Read our API documentation diff --git a/lib/singlepass-backend/README.md b/lib/singlepass-backend/README.md index e63e6f1b661..4460dcd2707 100644 --- a/lib/singlepass-backend/README.md +++ b/lib/singlepass-backend/README.md @@ -15,7 +15,7 @@ Join the Wasmer Community - Number of downloads from crates.io + Number of downloads from crates.io Read our API documentation diff --git a/lib/spectests/README.md b/lib/spectests/README.md index 0d3c248e04b..da05683ea2c 100644 --- a/lib/spectests/README.md +++ b/lib/spectests/README.md @@ -15,7 +15,7 @@ Join the Wasmer Community - Number of downloads from crates.io + Number of downloads from crates.io Read our API documentation