From 0775d496d3dfa9df6c078c17a9b97b682e23b487 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 12 Nov 2019 15:12:31 +0100 Subject: [PATCH 1/5] feat(runtime-core) Replace the `field-offset` crate by a custom `offset_of!` macro. The `field-offset` crate is unmaintained. When using its `offset_of!` macro on a struct with a field of type `std::ptr::NonNull`, in release mode, it generates a sigill. This patch removes the `field-offset` crate, and implements a custom `offset_of!` macro. --- Cargo.lock | 7 --- lib/runtime-core/Cargo.toml | 3 - lib/runtime-core/src/lib.rs | 4 -- lib/runtime-core/src/vm.rs | 114 ++++++++++++++++++++++++++---------- 4 files changed, 83 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0720c9eebbd..52ff96ffcbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,11 +417,6 @@ dependencies = [ "synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "field-offset" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -1529,7 +1524,6 @@ dependencies = [ "cc 1.0.46 (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)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1714,7 +1708,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" -"checksum field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64e9bc339e426139e02601fa69d101e96a92aee71b58bc01697ec2a63a5c9e68" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum generational-arena 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fd04ad33021a0409d3f1afbfb89d9f02c10caee73c28f5ac197474dd53e7cf7c" diff --git a/lib/runtime-core/Cargo.toml b/lib/runtime-core/Cargo.toml index 0acbe718ede..ba40447fbe9 100644 --- a/lib/runtime-core/Cargo.toml +++ b/lib/runtime-core/Cargo.toml @@ -42,9 +42,6 @@ version = "0.8" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["memoryapi"] } -[dev-dependencies] -field-offset = "0.1" - [build-dependencies] blake2b_simd = "0.5" rustc_version = "0.2" diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index d8b558ebc07..eb506f4cb43 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -26,10 +26,6 @@ #![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")] #![doc(html_logo_url = "https://avatars3.githubusercontent.com/u/44205449?s=200&v=4")] -#[cfg(test)] -#[macro_use] -extern crate field_offset; - #[macro_use] extern crate serde_derive; diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 0584633dac8..b432dcd9a4b 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -711,78 +711,136 @@ impl Anyfunc { mod vm_offset_tests { use super::{Anyfunc, Ctx, ImportedFunc, InternalCtx, LocalGlobal, LocalMemory, LocalTable}; + // Inspired by https://internals.rust-lang.org/t/discussion-on-offset-of/7440/2. + macro_rules! offset_of { + ($struct:path, $field:ident) => {{ + fn offset() -> usize { + use std::mem; + + let structure = mem::MaybeUninit::<$struct>::uninit(); + + let &$struct { + $field: ref field, .. + } = unsafe { &*structure.as_ptr() }; + + let offset = + (field as *const _ as usize).wrapping_sub(&structure as *const _ as usize); + + assert!((0..=mem::size_of_val(&structure)).contains(&offset)); + + offset + } + + offset() + }}; + } + + #[test] + fn offset_of() { + use std::{mem, ptr::NonNull}; + + struct S0; + + #[repr(C)] + struct S1 { + f1: u8, + f2: u16, + f3: u32, + f4: u64, + f5: u128, + f6: f32, + f7: f64, + f8: NonNull, + f9: Option>, + f10: *mut S0, + z: u8, + } + + assert_eq!(offset_of!(S1, f1), 0); + assert_eq!(offset_of!(S1, f2), 2); + assert_eq!(offset_of!(S1, f3), 4); + assert_eq!(offset_of!(S1, f4), 8); + assert_eq!(offset_of!(S1, f5), 16); + assert_eq!(offset_of!(S1, f6), 32); + assert_eq!(offset_of!(S1, f7), 40); + assert_eq!(offset_of!(S1, f8), 40 + mem::size_of::()); + assert_eq!(offset_of!(S1, f9), 48 + mem::size_of::()); + assert_eq!(offset_of!(S1, f10), 56 + mem::size_of::()); + assert_eq!(offset_of!(S1, z), 64 + mem::size_of::()); + } + #[test] fn vmctx() { - assert_eq!(0usize, offset_of!(Ctx => internal).get_byte_offset(),); + assert_eq!(0usize, offset_of!(Ctx, internal)); assert_eq!( Ctx::offset_memories() as usize, - offset_of!(InternalCtx => memories).get_byte_offset(), + offset_of!(InternalCtx, memories), ); assert_eq!( Ctx::offset_tables() as usize, - offset_of!(InternalCtx => tables).get_byte_offset(), + offset_of!(InternalCtx, tables), ); assert_eq!( Ctx::offset_globals() as usize, - offset_of!(InternalCtx => globals).get_byte_offset(), + offset_of!(InternalCtx, globals), ); assert_eq!( Ctx::offset_imported_memories() as usize, - offset_of!(InternalCtx => imported_memories).get_byte_offset(), + offset_of!(InternalCtx, imported_memories), ); assert_eq!( Ctx::offset_imported_tables() as usize, - offset_of!(InternalCtx => imported_tables).get_byte_offset(), + offset_of!(InternalCtx, imported_tables), ); assert_eq!( Ctx::offset_imported_globals() as usize, - offset_of!(InternalCtx => imported_globals).get_byte_offset(), + offset_of!(InternalCtx, imported_globals), ); assert_eq!( Ctx::offset_imported_funcs() as usize, - offset_of!(InternalCtx => imported_funcs).get_byte_offset(), + offset_of!(InternalCtx, imported_funcs), ); assert_eq!( Ctx::offset_intrinsics() as usize, - offset_of!(InternalCtx => intrinsics).get_byte_offset(), + offset_of!(InternalCtx, intrinsics), ); assert_eq!( Ctx::offset_stack_lower_bound() as usize, - offset_of!(InternalCtx => stack_lower_bound).get_byte_offset(), + offset_of!(InternalCtx, stack_lower_bound), ); assert_eq!( Ctx::offset_memory_base() as usize, - offset_of!(InternalCtx => memory_base).get_byte_offset(), + offset_of!(InternalCtx, memory_base), ); assert_eq!( Ctx::offset_memory_bound() as usize, - offset_of!(InternalCtx => memory_bound).get_byte_offset(), + offset_of!(InternalCtx, memory_bound), ); assert_eq!( Ctx::offset_internals() as usize, - offset_of!(InternalCtx => internals).get_byte_offset(), + offset_of!(InternalCtx, internals), ); assert_eq!( Ctx::offset_interrupt_signal_mem() as usize, - offset_of!(InternalCtx => interrupt_signal_mem).get_byte_offset(), + offset_of!(InternalCtx, interrupt_signal_mem), ); assert_eq!( Ctx::offset_local_functions() as usize, - offset_of!(Ctx => local_functions).get_byte_offset(), + offset_of!(Ctx, local_functions), ); } @@ -790,12 +848,12 @@ mod vm_offset_tests { fn imported_func() { assert_eq!( ImportedFunc::offset_func() as usize, - offset_of!(ImportedFunc => func).get_byte_offset(), + offset_of!(ImportedFunc, func), ); assert_eq!( ImportedFunc::offset_vmctx() as usize, - offset_of!(ImportedFunc => vmctx).get_byte_offset(), + offset_of!(ImportedFunc, vmctx), ); } @@ -803,12 +861,12 @@ mod vm_offset_tests { fn local_table() { assert_eq!( LocalTable::offset_base() as usize, - offset_of!(LocalTable => base).get_byte_offset(), + offset_of!(LocalTable, base), ); assert_eq!( LocalTable::offset_count() as usize, - offset_of!(LocalTable => count).get_byte_offset(), + offset_of!(LocalTable, count), ); } @@ -816,12 +874,12 @@ mod vm_offset_tests { fn local_memory() { assert_eq!( LocalMemory::offset_base() as usize, - offset_of!(LocalMemory => base).get_byte_offset(), + offset_of!(LocalMemory, base), ); assert_eq!( LocalMemory::offset_bound() as usize, - offset_of!(LocalMemory => bound).get_byte_offset(), + offset_of!(LocalMemory, bound), ); } @@ -829,25 +887,19 @@ mod vm_offset_tests { fn local_global() { assert_eq!( LocalGlobal::offset_data() as usize, - offset_of!(LocalGlobal => data).get_byte_offset(), + offset_of!(LocalGlobal, data), ); } #[test] fn cc_anyfunc() { - assert_eq!( - Anyfunc::offset_func() as usize, - offset_of!(Anyfunc => func).get_byte_offset(), - ); + assert_eq!(Anyfunc::offset_func() as usize, offset_of!(Anyfunc, func),); - assert_eq!( - Anyfunc::offset_vmctx() as usize, - offset_of!(Anyfunc => ctx).get_byte_offset(), - ); + assert_eq!(Anyfunc::offset_vmctx() as usize, offset_of!(Anyfunc, ctx),); assert_eq!( Anyfunc::offset_sig_id() as usize, - offset_of!(Anyfunc => sig_id).get_byte_offset(), + offset_of!(Anyfunc, sig_id), ); } } From 82e4d8e6cc596a6563513a38f58d3f055d5784db Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 13 Nov 2019 15:54:09 +0100 Subject: [PATCH 2/5] feat(runtime-core) `func!` supports closures. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch allows to write: ```rs func!(|…| -> … { … }) ``` --- lib/runtime-core/src/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/runtime-core/src/macros.rs b/lib/runtime-core/src/macros.rs index a9dc6721cae..bb0c84fb279 100644 --- a/lib/runtime-core/src/macros.rs +++ b/lib/runtime-core/src/macros.rs @@ -47,7 +47,7 @@ macro_rules! trace { /// Helper macro to create a new `Func` object using the provided function pointer. #[macro_export] macro_rules! func { - ($func:path) => {{ + ($func:expr) => {{ $crate::Func::new($func) }}; } From 7b809a765f2e3134411f57bc46dd1f1c3eaf6cc8 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 13 Nov 2019 15:54:41 +0100 Subject: [PATCH 3/5] doc(runtime-core) Improve documentation of `func!`. This patch explains that `func!` can consume closures. --- lib/runtime-core/src/macros.rs | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/lib/runtime-core/src/macros.rs b/lib/runtime-core/src/macros.rs index bb0c84fb279..9005b115d11 100644 --- a/lib/runtime-core/src/macros.rs +++ b/lib/runtime-core/src/macros.rs @@ -45,6 +45,44 @@ macro_rules! trace { } /// Helper macro to create a new `Func` object using the provided function pointer. +/// +/// # Usage +/// +/// Function pointers or closures are supported. Closures can capture +/// their environment (with `move). The first parameter is likely to +/// be of kind `vm::Ctx`, though it can be optional. +/// +/// ``` +/// # use wasmer_runtime_core::{imports, func}; +/// # use wasmer_runtime_core::vm; +/// +/// // A function that has access to `vm::Ctx`. +/// fn func_with_vmctx(_: &mut vm::Ctx, n: i32) -> i32 { +/// n +/// } +/// +/// // A function that cannot access `vm::Ctx`. +/// fn func(n: i32) -> i32 { +/// n +/// } +/// +/// let i = 7; +/// +/// let import_object = imports! { +/// "env" => { +/// "foo" => func!(func_with_vmctx), +/// "bar" => func!(func), +/// // A closure with a captured environment, and an access to `vm::Ctx`. +/// "baz" => func!(move |_: &mut vm::Ctx, n: i32| -> i32 { +/// n + i +/// }), +/// // A closure without a captured environment, and no access to `vm::Ctx`. +/// "qux" => func!(|n: i32| -> i32 { +/// n +/// }), +/// }, +/// }; +/// ``` #[macro_export] macro_rules! func { ($func:expr) => {{ From c4dffd6f59d97c5ae6896aff7dfb6e96a602f13a Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 13 Nov 2019 15:55:45 +0100 Subject: [PATCH 4/5] doc(runtime-core) Fix typos. --- lib/runtime-core/src/macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/runtime-core/src/macros.rs b/lib/runtime-core/src/macros.rs index 9005b115d11..71e8c2e2f7a 100644 --- a/lib/runtime-core/src/macros.rs +++ b/lib/runtime-core/src/macros.rs @@ -94,12 +94,12 @@ macro_rules! func { /// /// [`ImportObject`]: struct.ImportObject.html /// -/// # Note: +/// # Note /// The `import` macro currently only supports /// importing functions. /// /// -/// # Usage: +/// # Usage /// ``` /// # use wasmer_runtime_core::{imports, func}; /// # use wasmer_runtime_core::vm::Ctx; From 9127eaf825f4f8ea9f1f82c7b064e799a5d3f6d8 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Wed, 13 Nov 2019 15:09:18 -0800 Subject: [PATCH 5/5] Add categories and keywords to `Cargo.toml`s --- lib/clif-backend/Cargo.toml | 2 ++ lib/emscripten/Cargo.toml | 2 ++ lib/llvm-backend/Cargo.toml | 4 ++++ lib/middleware-common/Cargo.toml | 2 ++ lib/runtime-c-api/Cargo.toml | 2 ++ lib/runtime-core/Cargo.toml | 2 ++ lib/runtime/Cargo.toml | 2 ++ lib/singlepass-backend/Cargo.toml | 2 ++ lib/wasi/Cargo.toml | 2 ++ 9 files changed, 20 insertions(+) diff --git a/lib/clif-backend/Cargo.toml b/lib/clif-backend/Cargo.toml index ff83c131541..b38e40b8266 100644 --- a/lib/clif-backend/Cargo.toml +++ b/lib/clif-backend/Cargo.toml @@ -5,6 +5,8 @@ description = "Wasmer runtime Cranelift compiler backend" license = "MIT" authors = ["The Wasmer Engineering Team "] repository = "https://github.com/wasmerio/wasmer" +keywords = ["wasm", "webassembly", "compiler", "JIT", "AOT"] +categories = ["wasm"] edition = "2018" readme = "README.md" diff --git a/lib/emscripten/Cargo.toml b/lib/emscripten/Cargo.toml index 104312256f3..3db03310fc0 100644 --- a/lib/emscripten/Cargo.toml +++ b/lib/emscripten/Cargo.toml @@ -5,6 +5,8 @@ description = "Wasmer runtime emscripten implementation library" license = "MIT" authors = ["The Wasmer Engineering Team "] repository = "https://github.com/wasmerio/wasmer" +keywords = ["wasm", "webassembly", "ABI", "emscripten", "posix"] +categories = ["wasm"] edition = "2018" [dependencies] diff --git a/lib/llvm-backend/Cargo.toml b/lib/llvm-backend/Cargo.toml index b9c851b07e8..a728a9cec35 100644 --- a/lib/llvm-backend/Cargo.toml +++ b/lib/llvm-backend/Cargo.toml @@ -1,7 +1,11 @@ [package] name = "wasmer-llvm-backend" version = "0.10.1" +license = "MIT" authors = ["The Wasmer Engineering Team "] +repository = "https://github.com/wasmerio/wasmer" +keywords = ["wasm", "webassembly", "compiler", "JIT", "llvm"] +categories = ["wasm"] edition = "2018" readme = "README.md" diff --git a/lib/middleware-common/Cargo.toml b/lib/middleware-common/Cargo.toml index 5840729d632..1c325183df1 100644 --- a/lib/middleware-common/Cargo.toml +++ b/lib/middleware-common/Cargo.toml @@ -5,6 +5,8 @@ repository = "https://github.com/wasmerio/wasmer" description = "Wasmer runtime common middlewares" license = "MIT" authors = ["The Wasmer Engineering Team "] +keywords = ["wasm", "webassembly", "middleware", "metering"] +categories = ["wasm"] edition = "2018" [dependencies] diff --git a/lib/runtime-c-api/Cargo.toml b/lib/runtime-c-api/Cargo.toml index cc689e8892d..90d97ff8220 100644 --- a/lib/runtime-c-api/Cargo.toml +++ b/lib/runtime-c-api/Cargo.toml @@ -5,6 +5,8 @@ description = "Wasmer C API library" license = "MIT" authors = ["The Wasmer Engineering Team "] repository = "https://github.com/wasmerio/wasmer" +keywords = ["wasm", "webassembly", "runtime"] +categories = ["wasm"] edition = "2018" readme = "README.md" diff --git a/lib/runtime-core/Cargo.toml b/lib/runtime-core/Cargo.toml index 0acbe718ede..3d1b856ffdf 100644 --- a/lib/runtime-core/Cargo.toml +++ b/lib/runtime-core/Cargo.toml @@ -5,6 +5,8 @@ description = "Wasmer runtime core library" license = "MIT" authors = ["The Wasmer Engineering Team "] repository = "https://github.com/wasmerio/wasmer" +keywords = ["wasm", "webassembly", "runtime"] +categories = ["wasm"] edition = "2018" [dependencies] diff --git a/lib/runtime/Cargo.toml b/lib/runtime/Cargo.toml index 6e6be013cd0..8e272815a84 100644 --- a/lib/runtime/Cargo.toml +++ b/lib/runtime/Cargo.toml @@ -5,6 +5,8 @@ description = "Wasmer runtime library" license = "MIT" authors = ["The Wasmer Engineering Team "] repository = "https://github.com/wasmerio/wasmer" +keywords = ["wasm", "webassembly", "runtime", "sandbox", "secure"] +categories = ["wasm", "api-bindings"] edition = "2018" readme = "README.md" diff --git a/lib/singlepass-backend/Cargo.toml b/lib/singlepass-backend/Cargo.toml index 291d44455c9..5c28ff5e139 100644 --- a/lib/singlepass-backend/Cargo.toml +++ b/lib/singlepass-backend/Cargo.toml @@ -5,6 +5,8 @@ repository = "https://github.com/wasmerio/wasmer" description = "Wasmer runtime single pass compiler backend" license = "MIT" authors = ["The Wasmer Engineering Team "] +keywords = ["wasm", "webassembly", "compiler", "JIT", "AOT"] +categories = ["wasm"] edition = "2018" readme = "README.md" diff --git a/lib/wasi/Cargo.toml b/lib/wasi/Cargo.toml index 8a85acc2d07..6341ffb54f8 100644 --- a/lib/wasi/Cargo.toml +++ b/lib/wasi/Cargo.toml @@ -5,6 +5,8 @@ description = "Wasmer runtime WASI implementation library" license = "MIT" authors = ["The Wasmer Engineering Team "] repository = "https://github.com/wasmerio/wasmer" +keywords = ["wasm", "webassembly", "wasi", "sandbox", "ABI"] +categories = ["wasm"] edition = "2018" [dependencies]