diff --git a/.circleci/config.yml b/.circleci/config.yml index bd3a67532..3b85a39cf 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,6 +12,14 @@ run_install_dependencies: &run_install_dependencies version: 2 jobs: + changelog: + docker: + - image: docker:stable-git + steps: + - checkout + - run: + command: ! git diff --exit-code CHANGELOG.md + # Job used for testing lint: docker: @@ -367,6 +375,7 @@ workflows: version: 2 main: jobs: + - changelog - lint - test: filters: diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..4c283e930 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog + +All PRs to the Wasmer repository must add to this file. + +Blocks of changes will separated by version increments. + +## **[Unreleased]** +- [#348](https://github.com/wasmerio/wasmer/pull/348) Refactor internal runtime ↔️ backend abstraction. +- [#355](https://github.com/wasmerio/wasmer/pull/355) Misc changes to `Cargo.toml`s for publishing +- [#352](https://github.com/wasmerio/wasmer/pull/352) Bump version numbers to 0.3.0 +- [#351](https://github.com/wasmerio/wasmer/pull/351) Add hidden option to specify wasm program name (can be used to improve error messages) +- [#350](https://github.com/wasmerio/wasmer/pull/350) Enforce that CHANGELOG.md is updated through CI. +- [#349](https://github.com/wasmerio/wasmer/pull/349) Add [CHANGELOG.md](https://github.com/wasmerio/wasmer/blob/master/CHANGELOG.md). diff --git a/Cargo.lock b/Cargo.lock index 71c131da9..bf77b0390 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2230,19 +2230,19 @@ dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-clif-backend 0.2.0", - "wasmer-emscripten 0.2.1", - "wasmer-llvm-backend 0.1.0", - "wasmer-runtime 0.2.1", - "wasmer-runtime-abi 0.2.1", - "wasmer-runtime-core 0.2.1", - "wasmer-singlepass-backend 0.1.0", - "wasmer-wasi 0.2.1", + "wasmer-clif-backend 0.3.0", + "wasmer-emscripten 0.3.0", + "wasmer-llvm-backend 0.3.0", + "wasmer-runtime 0.3.0", + "wasmer-runtime-abi 0.3.0", + "wasmer-runtime-core 0.3.0", + "wasmer-singlepass-backend 0.3.0", + "wasmer-wasi 0.3.0", ] [[package]] name = "wasmer-clif-backend" -version = "0.2.0" +version = "0.3.0" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-codegen 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2258,15 +2258,15 @@ dependencies = [ "serde_bytes 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-runtime-core 0.2.1", - "wasmer-win-exception-handler 0.2.0", + "wasmer-runtime-core 0.3.0", + "wasmer-win-exception-handler 0.3.0", "wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasmer-emscripten" -version = "0.2.1" +version = "0.3.0" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2275,15 +2275,15 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-clif-backend 0.2.0", - "wasmer-llvm-backend 0.1.0", - "wasmer-runtime-core 0.2.1", - "wasmer-singlepass-backend 0.1.0", + "wasmer-clif-backend 0.3.0", + "wasmer-llvm-backend 0.3.0", + "wasmer-runtime-core 0.3.0", + "wasmer-singlepass-backend 0.3.0", ] [[package]] name = "wasmer-llvm-backend" -version = "0.1.0" +version = "0.3.0" dependencies = [ "capstone 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2298,35 +2298,35 @@ dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-runtime-core 0.2.1", + "wasmer-runtime-core 0.3.0", "wasmparser 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasmer-runtime" -version = "0.2.1" +version = "0.3.0" dependencies = [ "criterion 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-clif-backend 0.2.0", - "wasmer-llvm-backend 0.1.0", - "wasmer-runtime-core 0.2.1", - "wasmer-singlepass-backend 0.1.0", + "wasmer-clif-backend 0.3.0", + "wasmer-llvm-backend 0.3.0", + "wasmer-runtime-core 0.3.0", + "wasmer-singlepass-backend 0.3.0", ] [[package]] name = "wasmer-runtime-abi" -version = "0.2.1" +version = "0.3.0" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-runtime-core 0.2.1", + "wasmer-runtime-core 0.3.0", "wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", "zbox 0.6.1 (git+https://github.com/wasmerio/zbox?branch=bundle-libsodium)", "zstd 0.4.22+zstd.1.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2334,17 +2334,17 @@ dependencies = [ [[package]] name = "wasmer-runtime-c-api" -version = "0.2.1" +version = "0.3.0" dependencies = [ "cbindgen 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-runtime 0.2.1", - "wasmer-runtime-core 0.2.1", + "wasmer-runtime 0.3.0", + "wasmer-runtime-core 0.3.0", ] [[package]] name = "wasmer-runtime-core" -version = "0.2.1" +version = "0.3.0" dependencies = [ "blake2b_simd 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2363,13 +2363,14 @@ dependencies = [ "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", "wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasmer-singlepass-backend" -version = "0.1.0" +version = "0.3.0" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "dynasm 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2379,24 +2380,24 @@ dependencies = [ "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-runtime-core 0.2.1", + "wasmer-runtime-core 0.3.0", "wasmparser 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasmer-spectests" -version = "0.2.0" +version = "0.3.0" dependencies = [ "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-clif-backend 0.2.0", - "wasmer-llvm-backend 0.1.0", - "wasmer-runtime-core 0.2.1", - "wasmer-singlepass-backend 0.1.0", + "wasmer-clif-backend 0.3.0", + "wasmer-llvm-backend 0.3.0", + "wasmer-runtime-core 0.3.0", + "wasmer-singlepass-backend 0.3.0", ] [[package]] name = "wasmer-wasi" -version = "0.2.1" +version = "0.3.0" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2404,19 +2405,19 @@ dependencies = [ "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-runtime-core 0.2.1", + "wasmer-runtime-core 0.3.0", "zbox 0.6.1 (git+https://github.com/wasmerio/zbox?branch=bundle-libsodium)", ] [[package]] name = "wasmer-win-exception-handler" -version = "0.2.0" +version = "0.3.0" dependencies = [ "bindgen 0.46.0 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmer-runtime-core 0.2.1", + "wasmer-runtime-core 0.3.0", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/LICENSE b/LICENSE index 7e40523b0..079740dd3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,6 @@ -Copyright (c) 2019 Syrus Akbary +MIT License + +Copyright (c) 2019 Wasmer, Inc. and its affiliates. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/bors.toml b/bors.toml index c56141cd5..3ccbdc008 100644 --- a/bors.toml +++ b/bors.toml @@ -2,8 +2,9 @@ status = [ "ci/circleci: lint", "ci/circleci: test", "ci/circleci: test-macos", + "ci/circleci: test-rust-nightly", "continuous-integration/appveyor/branch" ] required_approvals = 1 timeout_sec = 900 -delete_merged_branches = true \ No newline at end of file +delete_merged_branches = true diff --git a/lib/clif-backend/Cargo.toml b/lib/clif-backend/Cargo.toml index ff151a220..9259a1903 100644 --- a/lib/clif-backend/Cargo.toml +++ b/lib/clif-backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-clif-backend" -version = "0.2.0" +version = "0.3.0" description = "Wasmer runtime Cranelift compiler backend" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -8,7 +8,7 @@ repository = "https://github.com/wasmerio/wasmer" edition = "2018" [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" } cranelift-native = "0.30.0" cranelift-codegen = "0.30.0" cranelift-entity = "0.30.0" @@ -33,7 +33,7 @@ version = "0.0.7" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] } -wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.2.0" } +wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.3.0" } [features] debug = ["wasmer-runtime-core/debug"] diff --git a/lib/clif-backend/src/module.rs b/lib/clif-backend/src/module.rs index 11f93342e..ad0576e59 100644 --- a/lib/clif-backend/src/module.rs +++ b/lib/clif-backend/src/module.rs @@ -73,16 +73,15 @@ impl Module { handler_data.clone(), )?; - let protected_caller = Caller::new(&self.info, handler_data, trampolines); - let cache_gen = Box::new(CacheGenerator::new( backend_cache, Arc::clone(&func_resolver.memory), )); + let runnable_module = Caller::new(handler_data, trampolines, func_resolver); + Ok(ModuleInner { - func_resolver: Box::new(func_resolver), - protected_caller: Box::new(protected_caller), + runnable_module: Box::new(runnable_module), cache_gen, info: self.info, @@ -103,16 +102,15 @@ impl Module { ) .map_err(|e| CacheError::Unknown(format!("{:?}", e)))?; - let protected_caller = Caller::new(&info, handler_data, trampolines); - let cache_gen = Box::new(CacheGenerator::new( backend_cache, Arc::clone(&func_resolver.memory), )); + let runnable_module = Caller::new(handler_data, trampolines, func_resolver); + Ok(ModuleInner { - func_resolver: Box::new(func_resolver), - protected_caller: Box::new(protected_caller), + runnable_module: Box::new(runnable_module), cache_gen, info, diff --git a/lib/clif-backend/src/resolver.rs b/lib/clif-backend/src/resolver.rs index e2706b6e1..a55bf56d7 100644 --- a/lib/clif-backend/src/resolver.rs +++ b/lib/clif-backend/src/resolver.rs @@ -21,7 +21,6 @@ use wasmer_runtime_core::cache::Error as CacheError; use wasmer_runtime_core::{ self, backend::{ - self, sys::{Memory, Protect}, SigRegistry, }, @@ -357,13 +356,8 @@ pub struct FuncResolver { pub(crate) memory: Arc, } -// Implements FuncResolver trait. -impl backend::FuncResolver for FuncResolver { - fn get( - &self, - _module: &wasmer_runtime_core::module::ModuleInner, - index: LocalFuncIndex, - ) -> Option> { +impl FuncResolver { + pub fn lookup(&self, index: LocalFuncIndex) -> Option> { lookup_func(&self.map, &self.memory, index) } } diff --git a/lib/clif-backend/src/signal/mod.rs b/lib/clif-backend/src/signal/mod.rs index 766ad75fb..f5fcf5d52 100644 --- a/lib/clif-backend/src/signal/mod.rs +++ b/lib/clif-backend/src/signal/mod.rs @@ -1,16 +1,14 @@ use crate::relocation::{TrapData, TrapSink}; +use crate::resolver::FuncResolver; use crate::trampoline::Trampolines; -use hashbrown::HashSet; use libc::c_void; use std::{any::Any, cell::Cell, ptr::NonNull, sync::Arc}; use wasmer_runtime_core::{ - backend::{ProtectedCaller, Token, UserTrapper}, - error::RuntimeResult, - export::Context, - module::{ExportIndex, ModuleInfo, ModuleInner}, + backend::{RunnableModule, UserTrapper}, + module::ModuleInfo, typed_func::{Wasm, WasmTrapInfo}, - types::{FuncIndex, FuncSig, LocalOrImport, SigIndex, Type, Value}, - vm::{self, ImportBacking}, + types::{LocalFuncIndex, SigIndex}, + vm, }; #[cfg(unix)] @@ -39,130 +37,44 @@ impl UserTrapper for Trapper { } pub struct Caller { - func_export_set: HashSet, handler_data: HandlerData, trampolines: Arc, + resolver: FuncResolver, } impl Caller { pub fn new( - module: &ModuleInfo, handler_data: HandlerData, trampolines: Arc, + resolver: FuncResolver, ) -> Self { - let mut func_export_set = HashSet::new(); - for export_index in module.exports.values() { - if let ExportIndex::Func(func_index) = export_index { - func_export_set.insert(*func_index); - } - } - if let Some(start_func_index) = module.start_func { - func_export_set.insert(start_func_index); - } - Self { - func_export_set, handler_data, trampolines, + resolver, } } } -impl ProtectedCaller for Caller { - fn call( - &self, - module: &ModuleInner, - func_index: FuncIndex, - params: &[Value], - import_backing: &ImportBacking, - vmctx: *mut vm::Ctx, - _: Token, - ) -> RuntimeResult> { - let (func_ptr, ctx, signature, sig_index) = - get_func_from_index(&module, import_backing, func_index); - - let vmctx_ptr = match ctx { - Context::External(external_vmctx) => external_vmctx, - Context::Internal => vmctx, - }; - - assert!(self.func_export_set.contains(&func_index)); - - assert!( - signature.returns().len() <= 1, - "multi-value returns not yet supported" - ); - - assert!( - signature.check_param_value_types(params), - "incorrect signature" - ); - - let param_vec: Vec = params - .iter() - .map(|val| match val { - Value::I32(x) => *x as u64, - Value::I64(x) => *x as u64, - Value::F32(x) => x.to_bits() as u64, - Value::F64(x) => x.to_bits(), - }) - .collect(); - - let mut return_vec = vec![0; signature.returns().len()]; - - let trampoline = self - .trampolines - .lookup(sig_index) - .expect("that trampoline doesn't exist"); - - #[cfg(not(target_os = "windows"))] - call_protected(&self.handler_data, || unsafe { - // Leap of faith. - trampoline( - vmctx_ptr, - func_ptr, - param_vec.as_ptr(), - return_vec.as_mut_ptr(), - ); - })?; - - // the trampoline is called from C on windows - #[cfg(target_os = "windows")] - call_protected( - &self.handler_data, - trampoline, - vmctx_ptr, - func_ptr, - param_vec.as_ptr(), - return_vec.as_mut_ptr(), - )?; - - Ok(return_vec - .iter() - .zip(signature.returns().iter()) - .map(|(&x, ty)| match ty { - Type::I32 => Value::I32(x as i32), - Type::I64 => Value::I64(x as i64), - Type::F32 => Value::F32(f32::from_bits(x as u32)), - Type::F64 => Value::F64(f64::from_bits(x as u64)), - }) - .collect()) +impl RunnableModule for Caller { + fn get_func(&self, _: &ModuleInfo, func_index: LocalFuncIndex) -> Option> { + self.resolver.lookup(func_index) } - fn get_wasm_trampoline(&self, module: &ModuleInner, sig_index: SigIndex) -> Option { + fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option { unsafe extern "C" fn invoke( trampoline: unsafe extern "C" fn(*mut vm::Ctx, NonNull, *const u64, *mut u64), ctx: *mut vm::Ctx, func: NonNull, args: *const u64, rets: *mut u64, - trap_info: *mut WasmTrapInfo, + _trap_info: *mut WasmTrapInfo, invoke_env: Option>, ) -> bool { let handler_data = &*invoke_env.unwrap().cast().as_ptr(); #[cfg(not(target_os = "windows"))] - let res = call_protected(handler_data, || unsafe { + let res = call_protected(handler_data, || { // Leap of faith. trampoline(ctx, func, args, rets); }) @@ -194,40 +106,6 @@ impl ProtectedCaller for Caller { } } -fn get_func_from_index<'a>( - module: &'a ModuleInner, - import_backing: &ImportBacking, - func_index: FuncIndex, -) -> (NonNull, Context, &'a FuncSig, SigIndex) { - let sig_index = *module - .info - .func_assoc - .get(func_index) - .expect("broken invariant, incorrect func index"); - - let (func_ptr, ctx) = match func_index.local_or_import(&module.info) { - LocalOrImport::Local(local_func_index) => ( - module - .func_resolver - .get(&module, local_func_index) - .expect("broken invariant, func resolver not synced with module.exports") - .cast(), - Context::Internal, - ), - LocalOrImport::Import(imported_func_index) => { - let imported_func = import_backing.imported_func(imported_func_index); - ( - NonNull::new(imported_func.func as *mut _).unwrap(), - Context::External(imported_func.vmctx), - ) - } - }; - - let signature = &module.info.signatures[sig_index]; - - (func_ptr, ctx, signature, sig_index) -} - unsafe impl Send for HandlerData {} unsafe impl Sync for HandlerData {} diff --git a/lib/clif-backend/src/trampoline.rs b/lib/clif-backend/src/trampoline.rs index 696a0b624..09ee4cf74 100644 --- a/lib/clif-backend/src/trampoline.rs +++ b/lib/clif-backend/src/trampoline.rs @@ -6,7 +6,6 @@ use cranelift_codegen::{ isa, Context, }; use hashbrown::HashMap; -use std::ffi::c_void; use std::{iter, mem, ptr::NonNull}; use wasmer_runtime_core::{ backend::sys::{Memory, Protect}, diff --git a/lib/emscripten/Cargo.toml b/lib/emscripten/Cargo.toml index 8b19340b0..6f37da948 100644 --- a/lib/emscripten/Cargo.toml +++ b/lib/emscripten/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-emscripten" -version = "0.2.1" +version = "0.3.0" description = "Wasmer runtime emscripten implementation library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -9,14 +9,14 @@ edition = "2018" build = "build/mod.rs" [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" } lazy_static = "1.2.0" libc = "0.2.49" byteorder = "1" time = "0.1.41" -wasmer-clif-backend = { path = "../clif-backend", version = "0.2.0" } -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.1.0", optional = true } -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.1.0", optional = true } +wasmer-clif-backend = { path = "../clif-backend", version = "0.3.0" } +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.3.0", optional = true } +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.3.0", optional = true } [target.'cfg(windows)'.dependencies] rand = "0.6" diff --git a/lib/emscripten/a.txt b/lib/emscripten/a.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib/emscripten/foo.txt b/lib/emscripten/foo.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib/emscripten/src/emscripten_target.rs b/lib/emscripten/src/emscripten_target.rs index 81444e2f9..5b14a1099 100644 --- a/lib/emscripten/src/emscripten_target.rs +++ b/lib/emscripten/src/emscripten_target.rs @@ -226,6 +226,10 @@ pub fn invoke_iiii(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: i32) -> i32 debug!("emscripten::invoke_iiii"); invoke!(ctx, dyn_call_iiii, index, a1, a2, a3) } +pub fn invoke_iifi(ctx: &mut Ctx, index: i32, a1: i32, a2: f64, a3: i32) -> i32 { + debug!("emscripten::invoke_iifi"); + invoke!(ctx, dyn_call_iifi, index, a1, a2, a3) +} pub fn invoke_v(ctx: &mut Ctx, index: i32) { debug!("emscripten::invoke_v"); invoke_no_return!(ctx, dyn_call_v, index); @@ -298,6 +302,33 @@ pub fn invoke_iiiiiiii( debug!("emscripten::invoke_iiiiiiii"); invoke!(ctx, dyn_call_iiiiiiii, index, a1, a2, a3, a4, a5, a6, a7) } +pub fn invoke_iiiiiiiii( + ctx: &mut Ctx, + index: i32, + a1: i32, + a2: i32, + a3: i32, + a4: i32, + a5: i32, + a6: i32, + a7: i32, + a8: i32, +) -> i32 { + debug!("emscripten::invoke_iiiiiiiii"); + invoke!( + ctx, + dyn_call_iiiiiiiii, + index, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8 + ) +} pub fn invoke_iiiiiiiiii( ctx: &mut Ctx, index: i32, @@ -327,6 +358,37 @@ pub fn invoke_iiiiiiiiii( a9 ) } +pub fn invoke_iiiiiiiiiii( + ctx: &mut Ctx, + index: i32, + a1: i32, + a2: i32, + a3: i32, + a4: i32, + a5: i32, + a6: i32, + a7: i32, + a8: i32, + a9: i32, + a10: i32, +) -> i32 { + debug!("emscripten::invoke_iiiiiiiiiii"); + invoke!( + ctx, + dyn_call_iiiiiiiiiii, + index, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10 + ) +} pub fn invoke_vd(ctx: &mut Ctx, index: i32, a1: f64) { debug!("emscripten::invoke_vd"); invoke_no_return!(ctx, dyn_call_vd, index, a1) @@ -450,13 +512,28 @@ pub fn invoke_viiiiiiiiii( ) } +pub fn invoke_iij(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: i32) -> i32 { + debug!("emscripten::invoke_iij"); + invoke!(ctx, dyn_call_iij, index, a1, a2, a3) +} + pub fn invoke_iiji(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: i32, a4: i32) -> i32 { debug!("emscripten::invoke_iiji"); - if let Some(dyn_call_iiji) = &get_emscripten_data(ctx).dyn_call_iiji { - dyn_call_iiji.call(index, a1, a2, a3, a4).unwrap() - } else { - panic!("dyn_call_iiji is set to None"); - } + invoke!(ctx, dyn_call_iiji, index, a1, a2, a3, a4) +} + +pub fn invoke_iiijj( + ctx: &mut Ctx, + index: i32, + a1: i32, + a2: i32, + a3: i32, + a4: i32, + a5: i32, + a6: i32, +) -> i32 { + debug!("emscripten::invoke_iiijj"); + invoke!(ctx, dyn_call_iiijj, index, a1, a2, a3, a4, a5, a6) } pub fn invoke_j(ctx: &mut Ctx, index: i32) -> i32 { debug!("emscripten::invoke_j"); @@ -655,11 +732,42 @@ pub fn invoke_vijj(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: i32, a4: i32 panic!("dyn_call_vijj is set to None"); } } +pub fn invoke_viid(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: f64) { + debug!("emscripten::invoke_viid"); + invoke_no_return!(ctx, dyn_call_viid, index, a1, a2, a3); +} pub fn invoke_viidii(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: f64, a4: i32, a5: i32) { debug!("emscripten::invoke_viidii"); - if let Some(dyn_call_viidii) = &get_emscripten_data(ctx).dyn_call_viidii { - dyn_call_viidii.call(index, a1, a2, a3, a4, a5).unwrap(); - } else { - panic!("dyn_call_viidii is set to None"); - } + invoke_no_return!(ctx, dyn_call_viidii, index, a1, a2, a3, a4, a5); +} +pub fn invoke_viidddddddd( + ctx: &mut Ctx, + index: i32, + a1: i32, + a2: i32, + a3: f64, + a4: f64, + a5: f64, + a6: f64, + a7: f64, + a8: f64, + a9: f64, + a10: f64, +) { + debug!("emscripten::invoke_viidddddddd"); + invoke_no_return!( + ctx, + dyn_call_viidddddddd, + index, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10 + ); } diff --git a/lib/emscripten/src/env/mod.rs b/lib/emscripten/src/env/mod.rs index 662d4ba94..2f799a679 100644 --- a/lib/emscripten/src/env/mod.rs +++ b/lib/emscripten/src/env/mod.rs @@ -47,6 +47,13 @@ pub fn _getpagesize(_ctx: &mut Ctx) -> u32 { 16384 } +pub fn _times(ctx: &mut Ctx, buffer: u32) -> u32 { + if buffer != 0 { + call_memset(ctx, buffer, 0, 16); + } + 0 +} + #[allow(clippy::cast_ptr_alignment)] pub fn ___build_environment(ctx: &mut Ctx, environ: c_int) { debug!("emscripten::___build_environment {}", environ); diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index 2086595e4..b3484770b 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -83,6 +83,7 @@ pub struct EmscriptenData<'a> { pub dyn_call_ii: Option>, pub dyn_call_iii: Option>, pub dyn_call_iiii: Option>, + pub dyn_call_iifi: Option>, pub dyn_call_v: Option>, pub dyn_call_vi: Option>, pub dyn_call_vii: Option>, @@ -96,8 +97,11 @@ pub struct EmscriptenData<'a> { pub dyn_call_iiiiii: Option>, pub dyn_call_iiiiiii: Option>, pub dyn_call_iiiiiiii: Option>, + pub dyn_call_iiiiiiiii: Option>, pub dyn_call_iiiiiiiiii: Option>, + pub dyn_call_iiiiiiiiiii: + Option>, pub dyn_call_vd: Option>, pub dyn_call_viiiii: Option>, pub dyn_call_viiiiii: Option>, @@ -106,7 +110,9 @@ pub struct EmscriptenData<'a> { pub dyn_call_viiiiiiiii: Option>, pub dyn_call_viiiiiiiiii: Option>, + pub dyn_call_iij: Option>, pub dyn_call_iiji: Option>, + pub dyn_call_iiijj: Option>, pub dyn_call_j: Option>, pub dyn_call_ji: Option>, pub dyn_call_jii: Option>, @@ -125,7 +131,10 @@ pub struct EmscriptenData<'a> { pub dyn_call_viji: Option>, pub dyn_call_vijiii: Option>, pub dyn_call_vijj: Option>, + pub dyn_call_viid: Option>, pub dyn_call_viidii: Option>, + pub dyn_call_viidddddddd: + Option>, pub temp_ret_0: i32, pub stack_save: Option>, @@ -149,6 +158,7 @@ impl<'a> EmscriptenData<'a> { let dyn_call_ii = instance.func("dynCall_ii").ok(); let dyn_call_iii = instance.func("dynCall_iii").ok(); let dyn_call_iiii = instance.func("dynCall_iiii").ok(); + let dyn_call_iifi = instance.func("dynCall_iifi").ok(); let dyn_call_v = instance.func("dynCall_v").ok(); let dyn_call_vi = instance.func("dynCall_vi").ok(); let dyn_call_vii = instance.func("dynCall_vii").ok(); @@ -162,7 +172,9 @@ impl<'a> EmscriptenData<'a> { let dyn_call_iiiiii = instance.func("dynCall_iiiiii").ok(); let dyn_call_iiiiiii = instance.func("dynCall_iiiiiii").ok(); let dyn_call_iiiiiiii = instance.func("dynCall_iiiiiiii").ok(); + let dyn_call_iiiiiiiii = instance.func("dynCall_iiiiiiiii").ok(); let dyn_call_iiiiiiiiii = instance.func("dynCall_iiiiiiiiii").ok(); + let dyn_call_iiiiiiiiiii = instance.func("dynCall_iiiiiiiiiii").ok(); let dyn_call_vd = instance.func("dynCall_vd").ok(); let dyn_call_viiiii = instance.func("dynCall_viiiii").ok(); let dyn_call_viiiiii = instance.func("dynCall_viiiiii").ok(); @@ -170,7 +182,9 @@ impl<'a> EmscriptenData<'a> { let dyn_call_viiiiiiii = instance.func("dynCall_viiiiiiii").ok(); let dyn_call_viiiiiiiii = instance.func("dynCall_viiiiiiiii").ok(); let dyn_call_viiiiiiiiii = instance.func("dynCall_viiiiiiiiii").ok(); + let dyn_call_iij = instance.func("dynCall_iij").ok(); let dyn_call_iiji = instance.func("dynCall_iiji").ok(); + let dyn_call_iiijj = instance.func("dynCall_iiijj").ok(); let dyn_call_j = instance.func("dynCall_j").ok(); let dyn_call_ji = instance.func("dynCall_ji").ok(); let dyn_call_jii = instance.func("dynCall_jii").ok(); @@ -188,7 +202,9 @@ impl<'a> EmscriptenData<'a> { let dyn_call_viji = instance.func("dynCall_viji").ok(); let dyn_call_vijiii = instance.func("dynCall_vijiii").ok(); let dyn_call_vijj = instance.func("dynCall_vijj").ok(); + let dyn_call_viid = instance.func("dynCall_viid").ok(); let dyn_call_viidii = instance.func("dynCall_viidii").ok(); + let dyn_call_viidddddddd = instance.func("dynCall_viidddddddd").ok(); let stack_save = instance.func("stackSave").ok(); let stack_restore = instance.func("stackRestore").ok(); @@ -205,6 +221,7 @@ impl<'a> EmscriptenData<'a> { dyn_call_ii, dyn_call_iii, dyn_call_iiii, + dyn_call_iifi, dyn_call_v, dyn_call_vi, dyn_call_vii, @@ -218,7 +235,9 @@ impl<'a> EmscriptenData<'a> { dyn_call_iiiiii, dyn_call_iiiiiii, dyn_call_iiiiiiii, + dyn_call_iiiiiiiii, dyn_call_iiiiiiiiii, + dyn_call_iiiiiiiiiii, dyn_call_vd, dyn_call_viiiii, dyn_call_viiiiii, @@ -226,7 +245,9 @@ impl<'a> EmscriptenData<'a> { dyn_call_viiiiiiii, dyn_call_viiiiiiiii, dyn_call_viiiiiiiiii, + dyn_call_iij, dyn_call_iiji, + dyn_call_iiijj, dyn_call_j, dyn_call_ji, dyn_call_jii, @@ -244,7 +265,9 @@ impl<'a> EmscriptenData<'a> { dyn_call_viji, dyn_call_vijiii, dyn_call_vijj, + dyn_call_viid, dyn_call_viidii, + dyn_call_viidddddddd, temp_ret_0: 0, stack_save, @@ -506,6 +529,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject "_getpagesize" => func!(crate::env::_getpagesize), "_sysconf" => func!(crate::env::_sysconf), "_getaddrinfo" => func!(crate::env::_getaddrinfo), + "_times" => func!(crate::env::_times), // Syscalls "___syscall1" => func!(crate::syscalls::___syscall1), @@ -657,6 +681,8 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject "_llvm_log2_f32" => func!(crate::math::_llvm_log2_f64), "_llvm_sin_f64" => func!(crate::math::_llvm_sin_f64), "_llvm_cos_f64" => func!(crate::math::_llvm_cos_f64), + "_llvm_exp2_f32" => func!(crate::math::_llvm_exp2_f32), + "_llvm_exp2_f64" => func!(crate::math::_llvm_exp2_f64), "_emscripten_random" => func!(crate::math::_emscripten_random), // Jump @@ -681,6 +707,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject "invoke_ii" => func!(crate::emscripten_target::invoke_ii), "invoke_iii" => func!(crate::emscripten_target::invoke_iii), "invoke_iiii" => func!(crate::emscripten_target::invoke_iiii), + "invoke_iifi" => func!(crate::emscripten_target::invoke_iifi), "invoke_v" => func!(crate::emscripten_target::invoke_v), "invoke_vi" => func!(crate::emscripten_target::invoke_vi), "invoke_vj" => func!(crate::emscripten_target::invoke_vj), @@ -727,7 +754,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject "invoke_iiiiii" => func!(crate::emscripten_target::invoke_iiiiii), "invoke_iiiiiii" => func!(crate::emscripten_target::invoke_iiiiiii), "invoke_iiiiiiii" => func!(crate::emscripten_target::invoke_iiiiiiii), + "invoke_iiiiiiiii" => func!(crate::emscripten_target::invoke_iiiiiiiii), "invoke_iiiiiiiiii" => func!(crate::emscripten_target::invoke_iiiiiiiiii), + "invoke_iiiiiiiiiii" => func!(crate::emscripten_target::invoke_iiiiiiiiiii), "invoke_vd" => func!(crate::emscripten_target::invoke_vd), "invoke_viiiii" => func!(crate::emscripten_target::invoke_viiiii), "invoke_viiiiii" => func!(crate::emscripten_target::invoke_viiiiii), @@ -736,7 +765,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject "invoke_viiiiiiiii" => func!(crate::emscripten_target::invoke_viiiiiiiii), "invoke_viiiiiiiii" => func!(crate::emscripten_target::invoke_viiiiiiiii), "invoke_viiiiiiiiii" => func!(crate::emscripten_target::invoke_viiiiiiiiii), + "invoke_iij" => func!(crate::emscripten_target::invoke_iij), "invoke_iiji" => func!(crate::emscripten_target::invoke_iiji), + "invoke_iiijj" => func!(crate::emscripten_target::invoke_iiijj), "invoke_j" => func!(crate::emscripten_target::invoke_j), "invoke_ji" => func!(crate::emscripten_target::invoke_ji), "invoke_jii" => func!(crate::emscripten_target::invoke_jii), @@ -753,7 +784,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject "invoke_viji" => func!(crate::emscripten_target::invoke_viji), "invoke_vijiii" => func!(crate::emscripten_target::invoke_vijiii), "invoke_vijj" => func!(crate::emscripten_target::invoke_vijj), + "invoke_viid" => func!(crate::emscripten_target::invoke_viid), "invoke_viidii" => func!(crate::emscripten_target::invoke_viidii), + "invoke_viidddddddd" => func!(crate::emscripten_target::invoke_viidddddddd), }; for null_func_name in globals.null_func_names.iter() { diff --git a/lib/emscripten/src/math.rs b/lib/emscripten/src/math.rs index 704a58854..e0eb10c7d 100644 --- a/lib/emscripten/src/math.rs +++ b/lib/emscripten/src/math.rs @@ -34,6 +34,16 @@ pub fn _llvm_log2_f32(_ctx: &mut Ctx, _value: f64) -> f64 { -1.0 } +pub fn _llvm_exp2_f32(_ctx: &mut Ctx, value: f32) -> f32 { + debug!("emscripten::_llvm_exp2_f32"); + 2f32.powf(value) +} + +pub fn _llvm_exp2_f64(_ctx: &mut Ctx, value: f64) -> f64 { + debug!("emscripten::_llvm_exp2_f64"); + 2f64.powf(value) +} + pub fn _emscripten_random(_ctx: &mut Ctx) -> f64 { debug!("emscripten::_emscripten_random"); -1.0 diff --git a/lib/llvm-backend/Cargo.toml b/lib/llvm-backend/Cargo.toml index 8be5aaa32..944db6d41 100644 --- a/lib/llvm-backend/Cargo.toml +++ b/lib/llvm-backend/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "wasmer-llvm-backend" -version = "0.1.0" +version = "0.3.0" authors = ["Lachlan Sneff "] edition = "2018" [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" } inkwell = { git = "https://github.com/wasmerio/inkwell", branch = "llvm7-0" } wasmparser = "0.28.0" hashbrown = "0.1.8" @@ -27,4 +27,4 @@ wabt = "0.7.4" [features] debug = ["wasmer-runtime-core/debug"] -disasm = ["capstone"] \ No newline at end of file +disasm = ["capstone"] diff --git a/lib/llvm-backend/src/backend.rs b/lib/llvm-backend/src/backend.rs index 927dbeca5..172d66726 100644 --- a/lib/llvm-backend/src/backend.rs +++ b/lib/llvm-backend/src/backend.rs @@ -18,15 +18,12 @@ use std::{ sync::Once, }; use wasmer_runtime_core::{ - backend::{FuncResolver, ProtectedCaller, Token, UserTrapper}, - error::{RuntimeError, RuntimeResult}, - export::Context, - module::{ModuleInfo, ModuleInner}, + backend::{RunnableModule, UserTrapper}, + module::ModuleInfo, structures::TypedIndex, typed_func::{Wasm, WasmTrapInfo}, - types::{FuncIndex, FuncSig, LocalFuncIndex, LocalOrImport, SigIndex, Type, Value}, - vm::{self, ImportBacking}, - vmcalls, + types::{LocalFuncIndex, SigIndex}, + vm, vmcalls, }; #[repr(C)] @@ -216,7 +213,7 @@ pub struct LLVMBackend { } impl LLVMBackend { - pub fn new(module: Module, _intrinsics: Intrinsics) -> (Self, LLVMProtectedCaller) { + pub fn new(module: Module, _intrinsics: Intrinsics) -> Self { Target::initialize_x86(&InitializationConfig { asm_parser: true, asm_printer: true, @@ -265,16 +262,21 @@ impl LLVMBackend { panic!("failed to load object") } - ( - Self { - module, - memory_buffer, - }, - LLVMProtectedCaller { module }, - ) + Self { + module, + memory_buffer, + } } +} - pub fn get_func( +impl Drop for LLVMBackend { + fn drop(&mut self) { + unsafe { module_delete(self.module) } + } +} + +impl RunnableModule for LLVMBackend { + fn get_func( &self, info: &ModuleInfo, local_func_index: LocalFuncIndex, @@ -291,126 +293,8 @@ impl LLVMBackend { NonNull::new(ptr as _) } -} -impl Drop for LLVMBackend { - fn drop(&mut self) { - unsafe { module_delete(self.module) } - } -} - -impl FuncResolver for LLVMBackend { - fn get( - &self, - module: &ModuleInner, - local_func_index: LocalFuncIndex, - ) -> Option> { - self.get_func(&module.info, local_func_index) - } -} - -struct Placeholder; - -unsafe impl Send for LLVMProtectedCaller {} -unsafe impl Sync for LLVMProtectedCaller {} - -pub struct LLVMProtectedCaller { - module: *mut LLVMModule, -} - -impl ProtectedCaller for LLVMProtectedCaller { - fn call( - &self, - module: &ModuleInner, - func_index: FuncIndex, - params: &[Value], - import_backing: &ImportBacking, - vmctx: *mut vm::Ctx, - _: Token, - ) -> RuntimeResult> { - let (func_ptr, ctx, signature, sig_index) = - get_func_from_index(&module, import_backing, func_index); - - let vmctx_ptr = match ctx { - Context::External(external_vmctx) => external_vmctx, - Context::Internal => vmctx, - }; - - assert!( - signature.returns().len() <= 1, - "multi-value returns not yet supported" - ); - - assert!( - signature.check_param_value_types(params), - "incorrect signature" - ); - - let param_vec: Vec = params - .iter() - .map(|val| match val { - Value::I32(x) => *x as u64, - Value::I64(x) => *x as u64, - Value::F32(x) => x.to_bits() as u64, - Value::F64(x) => x.to_bits(), - }) - .collect(); - - let mut return_vec = vec![0; signature.returns().len()]; - - let trampoline: unsafe extern "C" fn( - *mut vm::Ctx, - NonNull, - *const u64, - *mut u64, - ) = unsafe { - let name = if cfg!(target_os = "macos") { - format!("_trmp{}", sig_index.index()) - } else { - format!("trmp{}", sig_index.index()) - }; - - let c_str = CString::new(name).unwrap(); - let symbol = get_func_symbol(self.module, c_str.as_ptr()); - assert!(!symbol.is_null()); - - mem::transmute(symbol) - }; - - let mut trap_out = WasmTrapInfo::Unknown; - - // Here we go. - let success = unsafe { - invoke_trampoline( - trampoline, - vmctx_ptr, - func_ptr, - param_vec.as_ptr(), - return_vec.as_mut_ptr(), - &mut trap_out, - None, - ) - }; - - if success { - Ok(return_vec - .iter() - .zip(signature.returns().iter()) - .map(|(&x, ty)| match ty { - Type::I32 => Value::I32(x as i32), - Type::I64 => Value::I64(x as i64), - Type::F32 => Value::F32(f32::from_bits(x as u32)), - Type::F64 => Value::F64(f64::from_bits(x as u64)), - }) - .collect()) - } else { - Err(RuntimeError::Trap { - msg: trap_out.to_string().into(), - }) - } - } - - fn get_wasm_trampoline(&self, _module: &ModuleInner, sig_index: SigIndex) -> Option { + fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option { let trampoline: unsafe extern "C" fn( *mut vm::Ctx, NonNull, @@ -438,46 +322,14 @@ impl ProtectedCaller for LLVMProtectedCaller { } } +struct Placeholder; + impl UserTrapper for Placeholder { unsafe fn do_early_trap(&self, data: Box) -> ! { throw_any(Box::leak(data)) } } -fn get_func_from_index<'a>( - module: &'a ModuleInner, - import_backing: &ImportBacking, - func_index: FuncIndex, -) -> (NonNull, Context, &'a FuncSig, SigIndex) { - let sig_index = *module - .info - .func_assoc - .get(func_index) - .expect("broken invariant, incorrect func index"); - - let (func_ptr, ctx) = match func_index.local_or_import(&module.info) { - LocalOrImport::Local(local_func_index) => ( - module - .func_resolver - .get(&module, local_func_index) - .expect("broken invariant, func resolver not synced with module.exports") - .cast(), - Context::Internal, - ), - LocalOrImport::Import(imported_func_index) => { - let imported_func = import_backing.imported_func(imported_func_index); - ( - NonNull::new(imported_func.func as *mut _).unwrap(), - Context::External(imported_func.vmctx), - ) - } - }; - - let signature = &module.info.signatures[sig_index]; - - (func_ptr, ctx, signature, sig_index) -} - #[cfg(feature = "disasm")] unsafe fn disass_ptr(ptr: *const u8, size: usize, inst_count: usize) { use capstone::arch::BuildsCapstone; diff --git a/lib/llvm-backend/src/lib.rs b/lib/llvm-backend/src/lib.rs index 50b061731..bc43c5773 100644 --- a/lib/llvm-backend/src/lib.rs +++ b/lib/llvm-backend/src/lib.rs @@ -38,7 +38,7 @@ impl Compiler for LLVMCompiler { let (info, code_reader) = read_info::read_module(wasm, compiler_config).unwrap(); let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap(); - let (backend, protected_caller) = backend::LLVMBackend::new(module, intrinsics); + let backend = backend::LLVMBackend::new(module, intrinsics); // Create placeholder values here. let cache_gen = { @@ -61,8 +61,7 @@ impl Compiler for LLVMCompiler { }; Ok(ModuleInner { - func_resolver: Box::new(backend), - protected_caller: Box::new(protected_caller), + runnable_module: Box::new(backend), cache_gen, info, @@ -104,7 +103,9 @@ fn validate(bytes: &[u8]) -> Result<(), CompileError> { fn test_read_module() { use std::mem::transmute; use wabt::wat2wasm; - use wasmer_runtime_core::{structures::TypedIndex, types::LocalFuncIndex, vm, vmcalls}; + use wasmer_runtime_core::{ + backend::RunnableModule, structures::TypedIndex, types::LocalFuncIndex, vm, + }; // let wasm = include_bytes!("../../spectests/examples/simple/simple.wasm") as &[u8]; let wat = r#" (module @@ -122,7 +123,7 @@ fn test_read_module() { let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap(); - let (backend, _caller) = backend::LLVMBackend::new(module, intrinsics); + let backend = backend::LLVMBackend::new(module, intrinsics); let func_ptr = backend.get_func(&info, LocalFuncIndex::new(0)).unwrap(); diff --git a/lib/runtime-abi/Cargo.toml b/lib/runtime-abi/Cargo.toml index 19384647d..459c08de2 100644 --- a/lib/runtime-abi/Cargo.toml +++ b/lib/runtime-abi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-runtime-abi" -version = "0.2.1" +version = "0.3.0" description = "Wasmer runtime core library" license = "MIT" authors = ["The Wasmer Engineering Team "] diff --git a/lib/runtime-c-api/Cargo.toml b/lib/runtime-c-api/Cargo.toml index c0f5cdef2..881c37fcb 100644 --- a/lib/runtime-c-api/Cargo.toml +++ b/lib/runtime-c-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-runtime-c-api" -version = "0.2.1" +version = "0.3.0" description = "Wasmer C API library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -16,15 +16,15 @@ libc = "0.2" [dependencies.wasmer-runtime] path = "../runtime" -version = "0.2.1" +version = "0.3.0" [dependencies.wasmer-runtime-core] path = "../runtime-core" -version = "0.2.1" +version = "0.3.0" [features] debug = ["wasmer-runtime/debug"] llvm = ["wasmer-runtime/llvm"] [build-dependencies] -cbindgen = "0.8" \ No newline at end of file +cbindgen = "0.8" diff --git a/lib/runtime-core/Cargo.toml b/lib/runtime-core/Cargo.toml index 41d472626..e311be8fb 100644 --- a/lib/runtime-core/Cargo.toml +++ b/lib/runtime-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-runtime-core" -version = "0.2.1" +version = "0.3.0" description = "Wasmer runtime core library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -17,6 +17,7 @@ indexmap = "1.0.2" errno = "0.2.4" libc = "0.2.49" hex = "0.3.2" +smallvec = "0.6.9" # Dependencies for caching. [dependencies.serde] diff --git a/lib/runtime-core/src/backend.rs b/lib/runtime-core/src/backend.rs index 1044a7ee5..c6ecffcb0 100644 --- a/lib/runtime-core/src/backend.rs +++ b/lib/runtime-core/src/backend.rs @@ -1,10 +1,8 @@ use crate::{ - backing::ImportBacking, error::CompileResult, - error::RuntimeResult, module::ModuleInner, typed_func::Wasm, - types::{FuncIndex, LocalFuncIndex, SigIndex, Value}, + types::{LocalFuncIndex, SigIndex}, vm, }; @@ -67,59 +65,25 @@ pub trait Compiler { unsafe fn from_cache(&self, cache: Artifact, _: Token) -> Result; } -/// The functionality exposed by this trait is expected to be used -/// for calling functions exported by a webassembly module from -/// host code only. -pub trait ProtectedCaller: Send + Sync { - /// This calls the exported function designated by `local_func_index`. - /// Important to note, this supports calling imported functions that are - /// then exported. - /// - /// It's invalid to attempt to call a local function that isn't exported and - /// the implementation is expected to check for that. The implementation - /// is also expected to check for correct parameter types and correct - /// parameter number. - /// - /// The `returns` parameter is filled with dummy values when passed in and upon function - /// return, will be filled with the return values of the wasm function, as long as the - /// call completed successfully. - /// - /// The existance of the Token parameter ensures that this can only be called from - /// within the runtime crate. - /// - /// TODO(lachlan): Now that `get_wasm_trampoline` exists, `ProtectedCaller::call` - /// can be removed. That should speed up calls a little bit, since sanity checks - /// would only occur once. - fn call( - &self, - module: &ModuleInner, - func_index: FuncIndex, - params: &[Value], - import_backing: &ImportBacking, - vmctx: *mut vm::Ctx, - _: Token, - ) -> RuntimeResult>; - - /// A wasm trampoline contains the necesarry data to dynamically call an exported wasm function. - /// Given a particular signature index, we are returned a trampoline that is matched with that - /// signature and an invoke function that can call the trampoline. - fn get_wasm_trampoline(&self, module: &ModuleInner, sig_index: SigIndex) -> Option; - - fn get_early_trapper(&self) -> Box; -} - pub trait UserTrapper { unsafe fn do_early_trap(&self, data: Box) -> !; } -pub trait FuncResolver: Send + Sync { +pub trait RunnableModule: Send + Sync { /// This returns a pointer to the function designated by the `local_func_index` /// parameter. - fn get( + fn get_func( &self, - module: &ModuleInner, + info: &ModuleInfo, local_func_index: LocalFuncIndex, ) -> Option>; + + /// A wasm trampoline contains the necesarry data to dynamically call an exported wasm function. + /// Given a particular signature index, we are returned a trampoline that is matched with that + /// signature and an invoke function that can call the trampoline. + fn get_trampoline(&self, info: &ModuleInfo, sig_index: SigIndex) -> Option; + + fn get_early_trapper(&self) -> Box; } pub trait CacheGen: Send + Sync { diff --git a/lib/runtime-core/src/backing.rs b/lib/runtime-core/src/backing.rs index 48f2d2256..b79180ad6 100644 --- a/lib/runtime-core/src/backing.rs +++ b/lib/runtime-core/src/backing.rs @@ -72,8 +72,8 @@ impl LocalBacking { (0..module.info.func_assoc.len() - module.info.imported_functions.len()) .map(|index| { module - .func_resolver - .get(module, LocalFuncIndex::new(index)) + .runnable_module + .get_func(&module.info, LocalFuncIndex::new(index)) .unwrap() .as_ptr() as *const _ }) @@ -216,8 +216,8 @@ impl LocalBacking { let (func, ctx) = match func_index.local_or_import(&module.info) { LocalOrImport::Local(local_func_index) => ( module - .func_resolver - .get(module, local_func_index) + .runnable_module + .get_func(&module.info, local_func_index) .unwrap() .as_ptr() as *const vm::Func, @@ -255,8 +255,8 @@ impl LocalBacking { let (func, ctx) = match func_index.local_or_import(&module.info) { LocalOrImport::Local(local_func_index) => ( module - .func_resolver - .get(module, local_func_index) + .runnable_module + .get_func(&module.info, local_func_index) .unwrap() .as_ptr() as *const vm::Func, diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index 1249998cc..db9a2847f 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -1,18 +1,19 @@ use crate::{ - backend::Token, + backend::RunnableModule, backing::{ImportBacking, LocalBacking}, - error::{CallError, CallResult, ResolveError, ResolveResult, Result}, + error::{CallError, CallResult, ResolveError, ResolveResult, Result, RuntimeError}, export::{Context, Export, ExportIter, FuncPointer}, global::Global, import::{ImportObject, LikeNamespace}, memory::Memory, - module::{ExportIndex, Module, ModuleInner}, + module::{ExportIndex, Module, ModuleInfo, ModuleInner}, sig_registry::SigRegistry, table::Table, - typed_func::{Func, Wasm, WasmTypeList}, - types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value}, + typed_func::{Func, Wasm, WasmTrapInfo, WasmTypeList}, + types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Type, Value}, vm, }; +use smallvec::{smallvec, SmallVec}; use std::{mem, ptr::NonNull, sync::Arc}; pub(crate) struct InstanceInner { @@ -82,7 +83,45 @@ impl Instance { }; if let Some(start_index) = instance.module.info.start_func { - instance.call_with_index(start_index, &[])?; + // We know that the start function takes no arguments and returns no values. + // Therefore, we can call it without doing any signature checking, etc. + + let func_ptr = match start_index.local_or_import(&instance.module.info) { + LocalOrImport::Local(local_func_index) => instance + .module + .runnable_module + .get_func(&instance.module.info, local_func_index) + .unwrap(), + LocalOrImport::Import(import_func_index) => NonNull::new( + instance.inner.import_backing.vm_functions[import_func_index].func as *mut _, + ) + .unwrap(), + }; + + let ctx_ptr = match start_index.local_or_import(&instance.module.info) { + LocalOrImport::Local(_) => instance.inner.vmctx, + LocalOrImport::Import(imported_func_index) => { + instance.inner.import_backing.vm_functions[imported_func_index].vmctx + } + }; + + let sig_index = *instance + .module + .info + .func_assoc + .get(start_index) + .expect("broken invariant, incorrect func index"); + + let wasm_trampoline = instance + .module + .runnable_module + .get_trampoline(&instance.module.info, sig_index) + .expect("wasm trampoline"); + + let start_func: Func<(), (), Wasm> = + unsafe { Func::from_raw_parts(wasm_trampoline, func_ptr, ctx_ptr) }; + + start_func.call()?; } Ok(instance) @@ -147,15 +186,15 @@ impl Instance { let func_wasm_inner = self .module - .protected_caller - .get_wasm_trampoline(&self.module, sig_index) + .runnable_module + .get_trampoline(&self.module.info, sig_index) .unwrap(); let func_ptr = match func_index.local_or_import(&self.module.info) { LocalOrImport::Local(local_func_index) => self .module - .func_resolver - .get(&self.module, local_func_index) + .runnable_module + .get_func(&self.module.info, local_func_index) .unwrap(), LocalOrImport::Import(import_func_index) => NonNull::new( self.inner.import_backing.vm_functions[import_func_index].func as *mut _, @@ -245,7 +284,7 @@ impl Instance { /// # Ok(()) /// # } /// ``` - pub fn call(&self, name: &str, args: &[Value]) -> CallResult> { + pub fn call(&self, name: &str, params: &[Value]) -> CallResult> { let export_index = self.module .info @@ -264,7 +303,19 @@ impl Instance { .into()); }; - self.call_with_index(func_index, args) + let mut results = Vec::new(); + + call_func_with_index( + &self.module.info, + &*self.module.runnable_module, + &self.inner.import_backing, + self.inner.vmctx, + func_index, + params, + &mut results, + )?; + + Ok(results) } /// Returns an immutable reference to the @@ -295,45 +346,6 @@ impl Instance { } } -impl Instance { - fn call_with_index(&self, func_index: FuncIndex, args: &[Value]) -> CallResult> { - let sig_index = *self - .module - .info - .func_assoc - .get(func_index) - .expect("broken invariant, incorrect func index"); - let signature = &self.module.info.signatures[sig_index]; - - if !signature.check_param_value_types(args) { - Err(ResolveError::Signature { - expected: signature.clone(), - found: args.iter().map(|val| val.ty()).collect(), - })? - } - - let vmctx = match func_index.local_or_import(&self.module.info) { - LocalOrImport::Local(_) => self.inner.vmctx, - LocalOrImport::Import(imported_func_index) => { - self.inner.import_backing.vm_functions[imported_func_index].vmctx - } - }; - - let token = Token::generate(); - - let returns = self.module.protected_caller.call( - &self.module, - func_index, - args, - &self.inner.import_backing, - vmctx, - token, - )?; - - Ok(returns) - } -} - impl InstanceInner { pub(crate) fn get_export_from_index( &self, @@ -382,8 +394,8 @@ impl InstanceInner { let (func_ptr, ctx) = match func_index.local_or_import(&module.info) { LocalOrImport::Local(local_func_index) => ( module - .func_resolver - .get(&module, local_func_index) + .runnable_module + .get_func(&module.info, local_func_index) .expect("broken invariant, func resolver not synced with module.exports") .cast() .as_ptr() as *const _, @@ -452,6 +464,128 @@ impl LikeNamespace for Instance { } } +#[must_use] +fn call_func_with_index( + info: &ModuleInfo, + runnable: &dyn RunnableModule, + import_backing: &ImportBacking, + local_ctx: *mut vm::Ctx, + func_index: FuncIndex, + 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(); + 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) => { + runnable.get_func(info, local_func_index).unwrap() + } + LocalOrImport::Import(import_func_index) => { + NonNull::new(import_backing.vm_functions[import_func_index].func as *mut _).unwrap() + } + }; + + let ctx_ptr = match func_index.local_or_import(info) { + LocalOrImport::Local(_) => local_ctx, + LocalOrImport::Import(imported_func_index) => { + import_backing.vm_functions[imported_func_index].vmctx + } + }; + + let raw_args: SmallVec<[u64; 8]> = args + .iter() + .map(|v| match v { + Value::I32(i) => *i as u64, + Value::I64(i) => *i as u64, + Value::F32(f) => f.to_bits() as u64, + Value::F64(f) => f.to_bits(), + }) + .collect(); + + let Wasm { + trampoline, + invoke, + invoke_env, + } = runnable + .get_trampoline(info, sig_index) + .expect("wasm trampoline"); + + let run_wasm = |result_space: *mut u64| unsafe { + let mut trap_info = WasmTrapInfo::Unknown; + + let success = invoke( + trampoline, + ctx_ptr, + func_ptr, + raw_args.as_ptr(), + result_space, + &mut trap_info, + invoke_env, + ); + + if success { + Ok(()) + } else { + Err(RuntimeError::Trap { + msg: trap_info.to_string().into(), + }) + } + }; + + let raw_to_value = |raw, ty| match ty { + Type::I32 => Value::I32(raw as i32), + Type::I64 => Value::I64(raw as i64), + Type::F32 => Value::F32(f32::from_bits(raw as u32)), + Type::F64 => Value::F64(f64::from_bits(raw)), + }; + + match signature.returns() { + &[] => { + run_wasm(0 as *mut u64)?; + Ok(()) + } + &[ty] => { + let mut result = 0u64; + + run_wasm(&mut result)?; + + rets.push(raw_to_value(result, ty)); + + Ok(()) + } + result_tys @ _ => { + let mut results: SmallVec<[u64; 8]> = smallvec![0; num_results]; + + run_wasm(results.as_mut_ptr())?; + + rets.extend( + results + .iter() + .zip(result_tys.iter()) + .map(|(&raw, &ty)| raw_to_value(raw, ty)), + ); + + Ok(()) + } + } +} + /// A representation of an exported WebAssembly function. pub struct DynFunc<'a> { pub(crate) signature: Arc, @@ -484,32 +618,19 @@ impl<'a> DynFunc<'a> { /// # } /// ``` pub fn call(&self, params: &[Value]) -> CallResult> { - if !self.signature.check_param_value_types(params) { - Err(ResolveError::Signature { - expected: (*self.signature).clone(), - found: params.iter().map(|val| val.ty()).collect(), - })? - } + let mut results = Vec::new(); - let vmctx = match self.func_index.local_or_import(&self.module.info) { - LocalOrImport::Local(_) => self.instance_inner.vmctx, - LocalOrImport::Import(imported_func_index) => { - self.instance_inner.import_backing.vm_functions[imported_func_index].vmctx - } - }; - - let token = Token::generate(); - - let returns = self.module.protected_caller.call( - &self.module, + call_func_with_index( + &self.module.info, + &*self.module.runnable_module, + &self.instance_inner.import_backing, + self.instance_inner.vmctx, self.func_index, params, - &self.instance_inner.import_backing, - vmctx, - token, + &mut results, )?; - Ok(returns) + Ok(results) } pub fn signature(&self) -> &FuncSig { @@ -520,8 +641,8 @@ impl<'a> DynFunc<'a> { match self.func_index.local_or_import(&self.module.info) { LocalOrImport::Local(local_func_index) => self .module - .func_resolver - .get(self.module, local_func_index) + .runnable_module + .get_func(&self.module.info, local_func_index) .unwrap() .as_ptr(), LocalOrImport::Import(import_func_index) => { diff --git a/lib/runtime-core/src/module.rs b/lib/runtime-core/src/module.rs index 65817399d..9e9e93052 100644 --- a/lib/runtime-core/src/module.rs +++ b/lib/runtime-core/src/module.rs @@ -1,5 +1,5 @@ use crate::{ - backend::{Backend, FuncResolver, ProtectedCaller}, + backend::{Backend, RunnableModule}, cache::{Artifact, Error as CacheError}, error, import::ImportObject, @@ -22,9 +22,7 @@ use std::sync::Arc; /// This is used to instantiate a new WebAssembly module. #[doc(hidden)] pub struct ModuleInner { - pub func_resolver: Box, - pub protected_caller: Box, - + pub runnable_module: Box, pub cache_gen: Box, pub info: ModuleInfo, @@ -96,7 +94,7 @@ impl Module { pub(crate) fn new(inner: Arc) -> Self { unsafe { EARLY_TRAPPER - .with(|ucell| *ucell.get() = Some(inner.protected_caller.get_early_trapper())); + .with(|ucell| *ucell.get() = Some(inner.runnable_module.get_early_trapper())); } Module { inner } } diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index d18055ba1..5e38db628 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -71,9 +71,9 @@ pub type Invoke = unsafe extern "C" fn( /// as well as the environment that the invoke function may or may not require. #[derive(Copy, Clone)] pub struct Wasm { - trampoline: Trampoline, - invoke: Invoke, - invoke_env: Option>, + pub(crate) trampoline: Trampoline, + pub(crate) invoke: Invoke, + pub(crate) invoke_env: Option>, } impl Wasm { diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 3b2ca9938..1d955d40d 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -544,42 +544,23 @@ mod vm_ctx_tests { fn generate_module() -> ModuleInner { use super::Func; - use crate::backend::{ - sys::Memory, Backend, CacheGen, FuncResolver, ProtectedCaller, Token, UserTrapper, - }; + use crate::backend::{sys::Memory, Backend, CacheGen, RunnableModule, UserTrapper}; use crate::cache::Error as CacheError; - use crate::error::RuntimeResult; use crate::typed_func::Wasm; - use crate::types::{FuncIndex, LocalFuncIndex, SigIndex, Value}; + use crate::types::{LocalFuncIndex, SigIndex}; use hashbrown::HashMap; use std::ptr::NonNull; struct Placeholder; - impl FuncResolver for Placeholder { - fn get( + impl RunnableModule for Placeholder { + fn get_func( &self, - _module: &ModuleInner, + _module: &ModuleInfo, _local_func_index: LocalFuncIndex, ) -> Option> { None } - } - impl ProtectedCaller for Placeholder { - fn call( - &self, - _module: &ModuleInner, - _func_index: FuncIndex, - _params: &[Value], - _import_backing: &ImportBacking, - _vmctx: *mut Ctx, - _: Token, - ) -> RuntimeResult> { - Ok(vec![]) - } - fn get_wasm_trampoline( - &self, - _module: &ModuleInner, - _sig_index: SigIndex, - ) -> Option { + + fn get_trampoline(&self, _module: &ModuleInfo, _sig_index: SigIndex) -> Option { unimplemented!() } fn get_early_trapper(&self) -> Box { @@ -596,8 +577,7 @@ mod vm_ctx_tests { } ModuleInner { - func_resolver: Box::new(Placeholder), - protected_caller: Box::new(Placeholder), + runnable_module: Box::new(Placeholder), cache_gen: Box::new(Placeholder), info: ModuleInfo { memories: Map::new(), diff --git a/lib/runtime/Cargo.toml b/lib/runtime/Cargo.toml index f34798bf5..678d6861c 100644 --- a/lib/runtime/Cargo.toml +++ b/lib/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-runtime" -version = "0.2.1" +version = "0.3.0" description = "Wasmer runtime library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -9,17 +9,17 @@ edition = "2018" readme = "README.md" [dependencies] -wasmer-singlepass-backend = { path = "../singlepass-backend", optional = true } +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.3.0", optional = true } lazy_static = "1.2.0" memmap = "0.7.0" [dependencies.wasmer-runtime-core] path = "../runtime-core" -version = "0.2.1" +version = "0.3.0" [dependencies.wasmer-clif-backend] path = "../clif-backend" -version = "0.2.0" +version = "0.3.0" optional = true [dev-dependencies] diff --git a/lib/singlepass-backend/Cargo.toml b/lib/singlepass-backend/Cargo.toml index 977a3eac6..51fa61319 100644 --- a/lib/singlepass-backend/Cargo.toml +++ b/lib/singlepass-backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-singlepass-backend" -version = "0.1.0" +version = "0.3.0" repository = "https://github.com/wasmerio/wasmer" description = "Wasmer runtime single pass compiler backend" license = "MIT" @@ -8,7 +8,7 @@ authors = ["The Wasmer Engineering Team "] edition = "2018" [dependencies] -wasmer-runtime-core = { path = "../runtime-core" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" } wasmparser = "0.28.0" dynasm = "0.3.1" dynasmrt = "0.3.1" diff --git a/lib/singlepass-backend/src/codegen.rs b/lib/singlepass-backend/src/codegen.rs index 798dea114..ee3ad277e 100644 --- a/lib/singlepass-backend/src/codegen.rs +++ b/lib/singlepass-backend/src/codegen.rs @@ -1,15 +1,15 @@ use wasmer_runtime_core::{ - backend::{FuncResolver, ProtectedCaller}, + backend::RunnableModule, module::ModuleInfo, structures::Map, types::{FuncIndex, FuncSig, SigIndex}, }; use wasmparser::{Operator, Type as WpType}; -pub trait ModuleCodeGenerator { +pub trait ModuleCodeGenerator { fn check_precondition(&mut self, module_info: &ModuleInfo) -> Result<(), CodegenError>; fn next_function(&mut self) -> Result<&mut FCG, CodegenError>; - fn finalize(self, module_info: &ModuleInfo) -> Result<(PC, FR), CodegenError>; + fn finalize(self, module_info: &ModuleInfo) -> Result; fn feed_signatures(&mut self, signatures: Map) -> Result<(), CodegenError>; fn feed_function_signatures( &mut self, diff --git a/lib/singlepass-backend/src/codegen_x64.rs b/lib/singlepass-backend/src/codegen_x64.rs index c574bfc14..b79aafd83 100644 --- a/lib/singlepass-backend/src/codegen_x64.rs +++ b/lib/singlepass-backend/src/codegen_x64.rs @@ -11,17 +11,16 @@ use smallvec::SmallVec; use std::ptr::NonNull; use std::{any::Any, collections::HashMap, sync::Arc}; use wasmer_runtime_core::{ - backend::{FuncResolver, ProtectedCaller, Token, UserTrapper}, - error::RuntimeResult, + backend::{RunnableModule, UserTrapper}, memory::MemoryType, - module::{ModuleInfo, ModuleInner}, + module::ModuleInfo, structures::{Map, TypedIndex}, typed_func::Wasm, types::{ FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex, - TableIndex, Type, Value, + TableIndex, Type, }, - vm::{self, ImportBacking, LocalGlobal, LocalMemory, LocalTable}, + vm::{self, LocalGlobal, LocalMemory, LocalTable}, vmcalls, }; use wasmparser::{Operator, Type as WpType}; @@ -132,7 +131,6 @@ pub struct X64FunctionCode { signatures: Arc>, function_signatures: Arc>, - begin_offset: AssemblyOffset, assembler: Option, function_labels: Option)>>, br_table_data: Option>>, @@ -154,7 +152,9 @@ unsafe impl Send for FuncPtr {} unsafe impl Sync for FuncPtr {} pub struct X64ExecutionContext { + #[allow(dead_code)] code: ExecutableBuffer, + #[allow(dead_code)] functions: Vec, function_pointers: Vec, signatures: Arc>, @@ -162,10 +162,6 @@ pub struct X64ExecutionContext { func_import_count: usize, } -pub struct X64RuntimeResolver { - local_function_pointers: Vec, -} - #[derive(Debug)] pub struct ControlFrame { pub label: DynamicLabel, @@ -182,86 +178,33 @@ pub enum IfElseState { Else, } -impl X64ExecutionContext { - fn get_runtime_resolver( +impl RunnableModule for X64ExecutionContext { + fn get_func( &self, - _module_info: &ModuleInfo, - ) -> Result { - Ok(X64RuntimeResolver { - local_function_pointers: self.function_pointers[self.func_import_count..].to_vec(), - }) - } -} - -impl FuncResolver for X64RuntimeResolver { - fn get( - &self, - _module: &ModuleInner, - _local_func_index: LocalFuncIndex, + _: &ModuleInfo, + local_func_index: LocalFuncIndex, ) -> Option> { - NonNull::new( - self.local_function_pointers[_local_func_index.index() as usize].0 as *mut vm::Func, - ) - } -} - -impl ProtectedCaller for X64ExecutionContext { - fn call( - &self, - _module: &ModuleInner, - _func_index: FuncIndex, - _params: &[Value], - _import_backing: &ImportBacking, - _vmctx: *mut vm::Ctx, - _: Token, - ) -> RuntimeResult> { - let index = _func_index.index() - self.func_import_count; - let ptr = self.code.ptr(self.functions[index].begin_offset); - let return_ty = self.functions[index].returns.last().cloned(); - let buffer: Vec = _params - .iter() - .rev() - .map(|x| match *x { - Value::I32(x) => x as u32 as u64, - Value::I64(x) => x as u64, - Value::F32(x) => f32::to_bits(x) as u64, - Value::F64(x) => f64::to_bits(x), - }) - .collect(); - let ret = unsafe { - protect_unix::call_protected(|| { - CONSTRUCT_STACK_AND_CALL_WASM( - buffer.as_ptr(), - buffer.as_ptr().offset(buffer.len() as isize), - _vmctx, - ptr as _, - ) - }) - }?; - Ok(if let Some(ty) = return_ty { - vec![match ty { - WpType::I32 => Value::I32(ret as i32), - WpType::I64 => Value::I64(ret as i64), - WpType::F32 => Value::F32(f32::from_bits(ret as u32)), - WpType::F64 => Value::F64(f64::from_bits(ret as u64)), - _ => unreachable!(), - }] - } else { - vec![] - }) + self.function_pointers[self.func_import_count..] + .get(local_func_index.index()) + .and_then(|ptr| NonNull::new(ptr.0 as *mut vm::Func)) } - fn get_wasm_trampoline(&self, module: &ModuleInner, sig_index: SigIndex) -> Option { + fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option { use std::ffi::c_void; use wasmer_runtime_core::typed_func::WasmTrapInfo; unsafe extern "C" fn invoke( - trampoline: unsafe extern "C" fn(*mut vm::Ctx, NonNull, *const u64, *mut u64), + _trampoline: unsafe extern "C" fn( + *mut vm::Ctx, + NonNull, + *const u64, + *mut u64, + ), ctx: *mut vm::Ctx, func: NonNull, args: *const u64, rets: *mut u64, - trap_info: *mut WasmTrapInfo, + _trap_info: *mut WasmTrapInfo, num_params_plus_one: Option>, ) -> bool { let args = ::std::slice::from_raw_parts( @@ -278,7 +221,9 @@ impl ProtectedCaller for X64ExecutionContext { ) }) { Ok(x) => { - *rets = x; + if !rets.is_null() { + *rets = x; + } true } Err(_) => false, @@ -330,9 +275,7 @@ impl X64ModuleCodeGenerator { } } -impl ModuleCodeGenerator - for X64ModuleCodeGenerator -{ +impl ModuleCodeGenerator for X64ModuleCodeGenerator { fn check_precondition(&mut self, _module_info: &ModuleInfo) -> Result<(), CodegenError> { Ok(()) } @@ -367,7 +310,6 @@ impl ModuleCodeGenerator Result<(X64ExecutionContext, X64RuntimeResolver), CodegenError> { + fn finalize(mut self, _: &ModuleInfo) -> Result { let (assembler, mut br_table_data) = match self.functions.last_mut() { Some(x) => (x.assembler.take().unwrap(), x.br_table_data.take().unwrap()), None => { @@ -431,17 +370,14 @@ impl ModuleCodeGenerator) -> Result<(), CodegenError> { diff --git a/lib/singlepass-backend/src/lib.rs b/lib/singlepass-backend/src/lib.rs index cdb275cd3..c388bee49 100644 --- a/lib/singlepass-backend/src/lib.rs +++ b/lib/singlepass-backend/src/lib.rs @@ -62,11 +62,10 @@ impl Compiler for SinglePassCompiler { ) -> CompileResult { let mut mcg = codegen_x64::X64ModuleCodeGenerator::new(); let info = parse::read_module(wasm, Backend::Singlepass, &mut mcg, &compiler_config)?; - let (ec, resolver) = mcg.finalize(&info)?; + let exec_context = mcg.finalize(&info)?; Ok(ModuleInner { cache_gen: Box::new(Placeholder), - func_resolver: Box::new(resolver), - protected_caller: Box::new(ec), + runnable_module: Box::new(exec_context), info: info, }) } diff --git a/lib/singlepass-backend/src/parse.rs b/lib/singlepass-backend/src/parse.rs index b198ea4c5..cb4d93296 100644 --- a/lib/singlepass-backend/src/parse.rs +++ b/lib/singlepass-backend/src/parse.rs @@ -1,7 +1,7 @@ use crate::codegen::{CodegenError, FunctionCodeGenerator, ModuleCodeGenerator}; use hashbrown::HashMap; use wasmer_runtime_core::{ - backend::{Backend, CompilerConfig, FuncResolver, ProtectedCaller}, + backend::{Backend, CompilerConfig, RunnableModule}, module::{ DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder, TableInitializer, @@ -63,10 +63,9 @@ fn validate(bytes: &[u8]) -> Result<(), LoadError> { } pub fn read_module< - MCG: ModuleCodeGenerator, + MCG: ModuleCodeGenerator, FCG: FunctionCodeGenerator, - PC: ProtectedCaller, - FR: FuncResolver, + RM: RunnableModule, >( wasm: &[u8], backend: Backend, diff --git a/lib/spectests/Cargo.toml b/lib/spectests/Cargo.toml index d19fdab6d..390e7ebe9 100644 --- a/lib/spectests/Cargo.toml +++ b/lib/spectests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-spectests" -version = "0.2.0" +version = "0.3.0" description = "Wasmer spectests library" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -9,10 +9,10 @@ edition = "2018" build = "build/mod.rs" [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.2.0" } -wasmer-clif-backend = { path = "../clif-backend", version = "0.2.0" } -wasmer-llvm-backend = { path = "../llvm-backend", version = "0.1.0", optional = true } -wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.1.0", optional = true } +wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" } +wasmer-clif-backend = { path = "../clif-backend", version = "0.3.0" } +wasmer-llvm-backend = { path = "../llvm-backend", version = "0.3.0", optional = true } +wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.3.0", optional = true } [build-dependencies] wabt = "0.7.2" diff --git a/lib/wasi/Cargo.toml b/lib/wasi/Cargo.toml index cdf1a45b4..87224d529 100644 --- a/lib/wasi/Cargo.toml +++ b/lib/wasi/Cargo.toml @@ -1,13 +1,14 @@ [package] name = "wasmer-wasi" -version = "0.2.1" +version = "0.3.0" +description = "Wasmer runtime WASI implementation library" license = "MIT" authors = ["The Wasmer Engineering Team "] repository = "https://github.com/wasmerio/wasmer" edition = "2018" [dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" } libc = "0.2.50" rand = "0.6.5" # wasmer-runtime-abi = { path = "../runtime-abi" } diff --git a/lib/win-exception-handler/Cargo.toml b/lib/win-exception-handler/Cargo.toml index 18855212b..c11d497bd 100644 --- a/lib/win-exception-handler/Cargo.toml +++ b/lib/win-exception-handler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-win-exception-handler" -version = "0.2.0" +version = "0.3.0" description = "Wasmer runtime exception handling for Windows" license = "MIT" authors = ["The Wasmer Engineering Team "] @@ -8,7 +8,7 @@ repository = "https://github.com/wasmerio/wasmer" edition = "2018" [target.'cfg(windows)'.dependencies] -wasmer-runtime-core = { path = "../runtime-core", version = "0.2.0" } +wasmer-runtime-core = { path = "../runtime-core", version = "0.3.0" } winapi = { version = "0.3", features = ["winbase", "errhandlingapi", "minwindef", "minwinbase", "winnt"] } libc = "0.2.49" diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index cc97810a9..414099f40 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -83,6 +83,9 @@ struct Run { #[structopt(long = "em-symbol-map", parse(from_os_str))] em_symbol_map: Option, + #[structopt(long = "command-name", hidden = true)] + command_name: Option, + /// Application arguments #[structopt(name = "--", raw(multiple = "true"))] args: Vec, @@ -300,12 +303,16 @@ fn execute_wasm(options: &Run) -> Result<(), String> { ( InstanceABI::WASI, wasmer_wasi::generate_import_object( - [options.path.to_str().unwrap().to_owned()] - .iter() - .chain(options.args.iter()) - .cloned() - .map(|arg| arg.into_bytes()) - .collect(), + if let Some(cn) = &options.command_name { + [cn.clone()] + } else { + [options.path.to_str().unwrap().to_owned()] + } + .iter() + .chain(options.args.iter()) + .cloned() + .map(|arg| arg.into_bytes()) + .collect(), env::vars() .map(|(k, v)| format!("{}={}", k, v).into_bytes()) .collect(), @@ -329,7 +336,11 @@ fn execute_wasm(options: &Run) -> Result<(), String> { &module, &mut instance, abi, - options.path.to_str().unwrap(), + if let Some(cn) = &options.command_name { + cn + } else { + options.path.to_str().unwrap() + }, options.args.iter().map(|arg| arg.as_str()).collect(), ) .map_err(|e| format!("{:?}", e))?; diff --git a/update_version_numbers.sh b/update_version_numbers.sh new file mode 100755 index 000000000..df7f38952 --- /dev/null +++ b/update_version_numbers.sh @@ -0,0 +1,17 @@ +PREVIOUS_VERSION='0.2.1' +NEXT_VERSION='0.3.0' + +# quick hack +fd Cargo.toml --exec sed -i '' "s/version = \"$PREVIOUS_VERSION\"/version = \"$NEXT_VERSION\"/" +echo "manually check changes to Cargo.toml" + +# Order to upload packages in +## runtime-core +## win-exception-handler +## clif-backend +## llvm-backend +## singlepass-backend +## emscripten +## wasi +## runtime +## runtime-c-api