From c9460e3a030a9b160de025636bdeda8593c5b3ce Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Thu, 9 Apr 2020 14:37:21 -0700 Subject: [PATCH] Migrate tests away from using `runtime` and `runtime_core` --- Cargo.lock | 1 + Cargo.toml | 5 +- lib/api/Cargo.toml | 1 + lib/api/src/lib.rs | 224 ++++++++++++++++++++++++++------ tests/emscripten.rs | 2 +- tests/emtests/_common.rs | 8 +- tests/exception_handling.rs | 2 +- tests/imports.rs | 5 +- tests/llvm_compile.rs | 8 +- tests/middleware_common.rs | 2 +- tests/override.rs | 2 +- tests/runtime_core_tests/mod.rs | 2 +- tests/spectest.rs | 5 +- tests/spectest_semantics.rs | 2 +- tests/wasi_serialization.rs | 3 +- tests/wasitests/_common.rs | 6 +- 16 files changed, 215 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71a71b8ab..dc0133cea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2735,6 +2735,7 @@ dependencies = [ name = "wasmer" version = "0.16.2" dependencies = [ + "serde", "wasmer-clif-backend", "wasmer-llvm-backend", "wasmer-runtime-core", diff --git a/Cargo.toml b/Cargo.toml index 310138723..23add2e44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,15 +91,18 @@ backend-cranelift = [ "wasmer-clif-backend/generate-debug-information", "wasmer-runtime-core/generate-debug-information", "wasmer-runtime/cranelift", + "wasmer/cranelift", ] backend-llvm = [ "wasmer-llvm-backend", "wasmer-runtime/llvm", - "wasmer-runtime-core/generate-debug-information-no-export-symbols" + "wasmer-runtime-core/generate-debug-information-no-export-symbols", + "wasmer/llvm", ] backend-singlepass = [ "wasmer-singlepass-backend", "wasmer-runtime/singlepass", + "wasmer/singlepass", ] wasi = ["wasmer-wasi"] experimental-io-devices = ["wasmer-wasi-experimental-io-devices"] diff --git a/lib/api/Cargo.toml b/lib/api/Cargo.toml index 85ed576b9..7ded597c4 100644 --- a/lib/api/Cargo.toml +++ b/lib/api/Cargo.toml @@ -10,6 +10,7 @@ license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +serde = { version = "1", features = ["derive"] } wasmer-runtime-core = { version = "0.16.2", path = "../runtime-core" } [dependencies.wasmer-singlepass-backend] diff --git a/lib/api/src/lib.rs b/lib/api/src/lib.rs index 3740a3fe3..535e45fcd 100644 --- a/lib/api/src/lib.rs +++ b/lib/api/src/lib.rs @@ -22,10 +22,14 @@ //! //! more info, what to do if you run into problems +#[macro_use] +extern crate serde; + pub use crate::module::*; pub use wasmer_runtime_core::instance::{DynFunc, Instance}; pub use wasmer_runtime_core::memory::Memory; pub use wasmer_runtime_core::table::Table; +pub use wasmer_runtime_core::typed_func::DynamicFunc; pub use wasmer_runtime_core::Func; pub use wasmer_runtime_core::{func, imports}; @@ -81,6 +85,187 @@ pub mod vm { pub use wasmer_runtime_core::vm::Ctx; } +pub mod compiler { + //! Types and functions for compiling wasm; + use crate::module::Module; + pub use wasmer_runtime_core::backend::{BackendCompilerConfig, Compiler, CompilerConfig}; + pub use wasmer_runtime_core::compile_with; + + /// Enum used to select which compiler should be used to generate code. + #[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)] + pub enum Backend { + #[cfg(feature = "singlepass")] + /// Singlepass backend + Singlepass, + #[cfg(feature = "cranelift")] + /// Cranelift backend + Cranelift, + #[cfg(feature = "llvm")] + /// LLVM backend + LLVM, + /// Auto backend + Auto, + } + + impl Backend { + /// Get a list of the currently enabled (via feature flag) backends. + pub fn variants() -> &'static [&'static str] { + &[ + #[cfg(feature = "singlepass")] + "singlepass", + #[cfg(feature = "cranelift")] + "cranelift", + #[cfg(feature = "llvm")] + "llvm", + "auto", + ] + } + + /// Stable string representation of the backend. + /// It can be used as part of a cache key, for example. + pub fn to_string(&self) -> &'static str { + match self { + #[cfg(feature = "singlepass")] + Backend::Singlepass => "singlepass", + #[cfg(feature = "cranelift")] + Backend::Cranelift => "cranelift", + #[cfg(feature = "llvm")] + Backend::LLVM => "llvm", + Backend::Auto => "auto", + } + } + } + + impl Default for Backend { + fn default() -> Self { + #[cfg(all(feature = "default-backend-singlepass", not(feature = "docs")))] + return Backend::Singlepass; + + #[cfg(any(feature = "default-backend-cranelift", feature = "docs"))] + return Backend::Cranelift; + + #[cfg(all(feature = "default-backend-llvm", not(feature = "docs")))] + return Backend::LLVM; + } + } + + impl std::str::FromStr for Backend { + type Err = String; + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + #[cfg(feature = "singlepass")] + "singlepass" => Ok(Backend::Singlepass), + #[cfg(feature = "cranelift")] + "cranelift" => Ok(Backend::Cranelift), + #[cfg(feature = "llvm")] + "llvm" => Ok(Backend::LLVM), + "auto" => Ok(Backend::Auto), + _ => Err(format!("The backend {} doesn't exist", s)), + } + } + } + + /// Compile WebAssembly binary code into a [`Module`]. + /// This function is useful if it is necessary to + /// compile a module before it can be instantiated + /// (otherwise, the [`instantiate`] function should be used). + /// + /// [`Module`]: struct.Module.html + /// [`instantiate`]: fn.instantiate.html + /// + /// # Params: + /// * `wasm`: A `&[u8]` containing the + /// binary code of the wasm module you want to compile. + /// # Errors: + /// If the operation fails, the function returns `Err(error::CompileError::...)`. + pub fn compile(wasm: &[u8]) -> crate::error::CompileResult { + wasmer_runtime_core::compile_with(&wasm[..], &default_compiler()) + } + + /// The same as `compile` but takes a `CompilerConfig` for the purpose of + /// changing the compiler's behavior + pub fn compile_with_config( + wasm: &[u8], + compiler_config: CompilerConfig, + ) -> crate::error::CompileResult { + wasmer_runtime_core::compile_with_config(&wasm[..], &default_compiler(), compiler_config) + } + + /// The same as `compile_with_config` but takes a `Compiler` for the purpose of + /// changing the backend. + pub fn compile_with_config_with( + wasm: &[u8], + compiler_config: CompilerConfig, + compiler: &dyn Compiler, + ) -> crate::error::CompileResult { + wasmer_runtime_core::compile_with_config(&wasm[..], compiler, compiler_config) + } + + /// Copied from runtime core; TODO: figure out what we want to do here + pub fn default_compiler() -> impl Compiler { + #[cfg(any( + all( + feature = "default-backend-llvm", + not(feature = "docs"), + any( + feature = "default-backend-cranelift", + feature = "default-backend-singlepass" + ) + ), + all( + not(feature = "docs"), + feature = "default-backend-cranelift", + feature = "default-backend-singlepass" + ) + ))] + compile_error!( + "The `default-backend-X` features are mutually exclusive. Please choose just one" + ); + + #[cfg(all(feature = "default-backend-llvm", not(feature = "docs")))] + use wasmer_llvm_backend::LLVMCompiler as DefaultCompiler; + + #[cfg(all(feature = "default-backend-singlepass", not(feature = "docs")))] + use wasmer_singlepass_backend::SinglePassCompiler as DefaultCompiler; + + #[cfg(any(feature = "default-backend-cranelift", feature = "docs"))] + use wasmer_clif_backend::CraneliftCompiler as DefaultCompiler; + + DefaultCompiler::new() + } + + /// Get the `Compiler` as a trait object for the given `Backend`. + /// Returns `Option` because support for the requested `Compiler` may + /// not be enabled by feature flags. + /// + /// To get a list of the enabled backends as strings, call `Backend::variants()`. + pub fn compiler_for_backend(backend: Backend) -> Option> { + match backend { + #[cfg(feature = "cranelift")] + Backend::Cranelift => Some(Box::new(wasmer_clif_backend::CraneliftCompiler::new())), + + #[cfg(any(feature = "singlepass"))] + Backend::Singlepass => Some(Box::new( + wasmer_singlepass_backend::SinglePassCompiler::new(), + )), + + #[cfg(feature = "llvm")] + Backend::LLVM => Some(Box::new(wasmer_llvm_backend::LLVMCompiler::new())), + + Backend::Auto => { + #[cfg(feature = "default-backend-singlepass")] + return Some(Box::new( + wasmer_singlepass_backend::SinglePassCompiler::new(), + )); + #[cfg(feature = "default-backend-cranelift")] + return Some(Box::new(wasmer_clif_backend::CraneliftCompiler::new())); + #[cfg(feature = "default-backend-llvm")] + return Some(Box::new(wasmer_llvm_backend::LLVMCompiler::new())); + } + } + } +} + // TODO: `import` or `imports`? pub mod import { //! Types and functions for Wasm imports. @@ -161,51 +346,16 @@ pub trait CompiledModule { fn validate(bytes: impl AsRef<[u8]>) -> error::CompileResult<()>; } -use wasmer_runtime_core::backend::Compiler; - -/// Copied from runtime core; TODO: figure out what we want to do here -pub fn default_compiler() -> impl Compiler { - #[cfg(any( - all( - feature = "default-backend-llvm", - not(feature = "docs"), - any( - feature = "default-backend-cranelift", - feature = "default-backend-singlepass" - ) - ), - all( - not(feature = "docs"), - feature = "default-backend-cranelift", - feature = "default-backend-singlepass" - ) - ))] - compile_error!( - "The `default-backend-X` features are mutually exclusive. Please choose just one" - ); - - #[cfg(all(feature = "default-backend-llvm", not(feature = "docs")))] - use wasmer_llvm_backend::LLVMCompiler as DefaultCompiler; - - #[cfg(all(feature = "default-backend-singlepass", not(feature = "docs")))] - use wasmer_singlepass_backend::SinglePassCompiler as DefaultCompiler; - - #[cfg(any(feature = "default-backend-cranelift", feature = "docs"))] - use wasmer_clif_backend::CraneliftCompiler as DefaultCompiler; - - DefaultCompiler::new() -} - // this implementation should be moved impl CompiledModule for Module { fn new(bytes: impl AsRef<[u8]>) -> error::CompileResult { let bytes = bytes.as_ref(); - wasmer_runtime_core::compile_with(bytes, &default_compiler()) + wasmer_runtime_core::compile_with(bytes, &compiler::default_compiler()) } fn from_binary(bytes: impl AsRef<[u8]>) -> error::CompileResult { let bytes = bytes.as_ref(); - wasmer_runtime_core::compile_with(bytes, &default_compiler()) + wasmer_runtime_core::compile_with(bytes, &compiler::default_compiler()) } fn from_binary_unchecked(bytes: impl AsRef<[u8]>) -> error::CompileResult { diff --git a/tests/emscripten.rs b/tests/emscripten.rs index 4edf595a2..3195881e0 100644 --- a/tests/emscripten.rs +++ b/tests/emscripten.rs @@ -2,8 +2,8 @@ mod tests { use std::sync::Arc; use wabt::wat2wasm; + use wasmer::compiler::compile; use wasmer_emscripten::is_emscripten_module; - use wasmer_runtime::compile; #[test] fn should_detect_emscripten_files() { diff --git a/tests/emtests/_common.rs b/tests/emtests/_common.rs index 8808e704a..0547a002a 100644 --- a/tests/emtests/_common.rs +++ b/tests/emtests/_common.rs @@ -1,5 +1,5 @@ use std::env; -use wasmer_runtime::Backend; +use wasmer::compiler::Backend; pub fn get_backend() -> Option { #[cfg(feature = "backend-cranelift")] @@ -41,9 +41,9 @@ macro_rules! assert_emscripten_output { let wasm_bytes = include_bytes!($file); let backend = $crate::emtests::_common::get_backend().expect("Please set one of `WASMER_TEST_CRANELIFT`, `WASMER_TEST_LLVM`, or `WASMER_TEST_SINGELPASS` to `1`."); - let compiler = wasmer_runtime::compiler_for_backend(backend).expect("The desired compiler was not found!"); + let compiler = wasmer::compiler::compiler_for_backend(backend).expect("The desired compiler was not found!"); - let module = wasmer_runtime::compile_with_config_with(&wasm_bytes[..], Default::default(), &*compiler).expect("WASM can't be compiled"); + let module = wasmer::compiler::compile_with_config_with(&wasm_bytes[..], Default::default(), &*compiler).expect("WASM can't be compiled"); let mut emscripten_globals = EmscriptenGlobals::new(&module).expect("globals are valid"); let import_object = generate_emscripten_env(&mut emscripten_globals); @@ -79,7 +79,7 @@ macro_rules! assert_emscripten_output { // use wasmer_clif_backend::CraneliftCompiler; // use wasmer_emscripten::{generate_emscripten_env, stdio::StdioCapturer, EmscriptenGlobals}; -// let module = wasmer_runtime_core::compile_with(&wasm_bytes[..], &CraneliftCompiler::new()) +// let module = wasmer::compiler::compile_with(&wasm_bytes[..], &CraneliftCompiler::new()) // .expect("WASM can't be compiled"); // let mut emscripten_globals = EmscriptenGlobals::new(&module); diff --git a/tests/exception_handling.rs b/tests/exception_handling.rs index 7a590527d..d545b5cfb 100644 --- a/tests/exception_handling.rs +++ b/tests/exception_handling.rs @@ -2,8 +2,8 @@ mod runtime_core_tests; pub mod runtime_core_exception_handling { use super::runtime_core_tests::{get_compiler, wat2wasm}; + use wasmer::compiler::compile_with; use wasmer::imports; - use wasmer_runtime_core::compile_with; #[test] fn exception_handling_works() { diff --git a/tests/imports.rs b/tests/imports.rs index b8572be4e..dbf99f6ac 100644 --- a/tests/imports.rs +++ b/tests/imports.rs @@ -5,14 +5,13 @@ pub mod runtime_core_imports { use super::runtime_core_tests::{get_compiler, wat2wasm}; use std::{convert::TryInto, sync::Arc}; + use wasmer::compiler::compile_with; use wasmer::error::RuntimeError; - use wasmer::imports; use wasmer::units::Pages; - use wasmer::vm; use wasmer::wasm::{ DynFunc, Func, FuncSig, Global, Instance, Memory, MemoryDescriptor, Type, Value, }; - use wasmer_runtime_core::{compile_with, typed_func::DynamicFunc}; + use wasmer::{imports, vm, DynamicFunc}; #[test] fn runtime_core_new_api_works() { diff --git a/tests/llvm_compile.rs b/tests/llvm_compile.rs index b389ab0c2..2e9896f6f 100644 --- a/tests/llvm_compile.rs +++ b/tests/llvm_compile.rs @@ -10,17 +10,17 @@ )] use wabt::wat2wasm; +use wasmer::compiler::Compiler; use wasmer_llvm_backend::LLVMCompiler; -use wasmer_runtime_core::backend::Compiler; pub fn get_compiler() -> impl Compiler { LLVMCompiler::new() } +use wasmer::compiler::CompilerConfig; +use wasmer::compiler::{compile_with, compile_with_config_with, BackendCompilerConfig}; use wasmer::imports; use wasmer_llvm_backend::{InkwellModule, LLVMBackendConfig, LLVMCallbacks}; -use wasmer_runtime::CompilerConfig; -use wasmer_runtime_core::{backend::BackendCompilerConfig, compile_with, compile_with_config}; use std::cell::RefCell; use std::rc::Rc; @@ -74,7 +74,7 @@ fn crash_select_with_mismatched_pending() { ..Default::default() }; let wasm_binary = wat2wasm(WAT.as_bytes()).expect("WAST not valid or malformed"); - let module = compile_with_config(&wasm_binary, &get_compiler(), compiler_config).unwrap(); + let module = compile_with_config_with(&wasm_binary, compiler_config, &get_compiler()).unwrap(); module.instantiate(&imports! {}).unwrap(); const LLVM: &str = r#" %s3 = fadd double 0.000000e+00, %s2 diff --git a/tests/middleware_common.rs b/tests/middleware_common.rs index 67cd67b55..db0ee18f8 100644 --- a/tests/middleware_common.rs +++ b/tests/middleware_common.rs @@ -2,6 +2,7 @@ mod tests { use wabt::wat2wasm; + use wasmer::compiler::{compile_with, Compiler}; use wasmer::imports; use wasmer::wasm::Func; use wasmer_middleware_common::metering::*; @@ -9,7 +10,6 @@ mod tests { use wasmer_runtime_core::codegen::{MiddlewareChain, StreamingCompiler}; use wasmer_runtime_core::fault::{pop_code_version, push_code_version}; use wasmer_runtime_core::state::CodeVersion; - use wasmer_runtime_core::{backend::Compiler, compile_with}; #[cfg(feature = "backend-llvm")] use wasmer_llvm_backend::ModuleCodeGenerator as MCG; diff --git a/tests/override.rs b/tests/override.rs index 278e55c51..24bebd917 100644 --- a/tests/override.rs +++ b/tests/override.rs @@ -1,10 +1,10 @@ use wabt::wat2wasm; +use wasmer::compiler::compile; use wasmer::{ import::ImportObject, wasm::{Instance, Value}, DynFunc, }; -use wasmer_runtime::compile; #[test] fn override_works() { diff --git a/tests/runtime_core_tests/mod.rs b/tests/runtime_core_tests/mod.rs index 96f7e6265..4e72fe395 100644 --- a/tests/runtime_core_tests/mod.rs +++ b/tests/runtime_core_tests/mod.rs @@ -1,5 +1,5 @@ pub use wabt::wat2wasm; -use wasmer_runtime_core::backend::Compiler; +use wasmer::compiler::Compiler; #[cfg(feature = "backend-cranelift")] pub fn get_compiler() -> impl Compiler { diff --git a/tests/spectest.rs b/tests/spectest.rs index 975904a71..48a2ab942 100644 --- a/tests/spectest.rs +++ b/tests/spectest.rs @@ -272,6 +272,7 @@ mod tests { use std::str::FromStr; use wabt::script::{Action, Command, CommandKind, ScriptParser, Value}; use wasmer::{ + compiler::{compile_with_config_with, compiler_for_backend, Backend, CompilerConfig}, error::CompileError, func, import::{ImportObject, LikeNamespace}, @@ -281,9 +282,7 @@ mod tests { vm::Ctx, wasm::{self, Global, Instance, Memory, MemoryDescriptor, Table, TableDescriptor}, }; - use wasmer_runtime::{ - compile_with_config_with, compiler_for_backend, Backend, CompilerConfig, Export, Features, - }; + use wasmer_runtime::{Export, Features}; fn format_panic(e: &dyn std::any::Any) -> String { if let Some(s) = e.downcast_ref::<&str>() { diff --git a/tests/spectest_semantics.rs b/tests/spectest_semantics.rs index 26b704c1b..c92a26d63 100644 --- a/tests/spectest_semantics.rs +++ b/tests/spectest_semantics.rs @@ -19,7 +19,7 @@ mod tests { (elem (;0;) (i32.const 0) 0)) "#; let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); - let module = wasmer_runtime::compile(&wasm_binary[..]).expect("WASM can't be compiled"); + let module = wasmer::compiler::compile(&wasm_binary[..]).expect("WASM can't be compiled"); let instance = module .instantiate(&ImportObject::new()) .expect("WASM can't be instantiated"); diff --git a/tests/wasi_serialization.rs b/tests/wasi_serialization.rs index b588ddf36..5438d0d52 100644 --- a/tests/wasi_serialization.rs +++ b/tests/wasi_serialization.rs @@ -1,6 +1,5 @@ #![cfg(test)] -use wasmer::{vm::Ctx, Func}; -use wasmer_runtime::compile; +use wasmer::{compiler::compile, vm::Ctx, Func}; use wasmer_wasi::{state::*, *}; use std::ffi::c_void; diff --git a/tests/wasitests/_common.rs b/tests/wasitests/_common.rs index 248eee46d..12bde2992 100644 --- a/tests/wasitests/_common.rs +++ b/tests/wasitests/_common.rs @@ -1,5 +1,5 @@ use std::env; -use wasmer_runtime::Backend; +use wasmer::compiler::Backend; pub fn get_backend() -> Option { #[cfg(feature = "backend-cranelift")] @@ -38,9 +38,9 @@ macro_rules! assert_wasi_output { let wasm_bytes = include_bytes!($file); let backend = $crate::wasitests::_common::get_backend().expect("Please set one of `WASMER_TEST_CRANELIFT`, `WASMER_TEST_LLVM`, or `WASMER_TEST_SINGELPASS` to `1`."); - let compiler = wasmer_runtime::compiler_for_backend(backend).expect("The desired compiler was not found!"); + let compiler = wasmer::compiler::compiler_for_backend(backend).expect("The desired compiler was not found!"); - let module = wasmer_runtime::compile_with_config_with(&wasm_bytes[..], Default::default(), &*compiler).expect("WASM can't be compiled"); + let module = wasmer::compiler::compile_with_config_with(&wasm_bytes[..], Default::default(), &*compiler).expect("WASM can't be compiled"); let wasi_version = get_wasi_version(&module, true).expect("WASI module");