diff --git a/CHANGELOG.md b/CHANGELOG.md index 33e8f406bd7..f07f9344fd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ Looking for changes that affect our C API? See the [C API Changelog](lib/c-api/C ## **Unreleased** +### Changed +- #2946 Remove dylib,staticlib engines in favor of a single Universal engine + ### Fixed - [#2942](https://github.com/wasmerio/wasmer/pull/2942) Fix clippy lints. - [#2943](https://github.com/wasmerio/wasmer/pull/2943) Fix build error on some archs by using c_char instead of i8 diff --git a/Cargo.lock b/Cargo.lock index f36ce7f52f4..919adaecb69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,7 +160,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "which 3.1.1", + "which", ] [[package]] @@ -1881,6 +1881,7 @@ checksum = "517a3034eb2b1499714e9d1e49b2367ad567e07639b69776d35e259d9c27cca6" dependencies = [ "bytecheck", "hashbrown 0.12.1", + "indexmap", "ptr_meta", "rend", "rkyv_derive", @@ -1934,7 +1935,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.9", + "semver 1.0.10", ] [[package]] @@ -2033,9 +2034,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" +checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c" [[package]] name = "semver-parser" @@ -2458,9 +2459,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" +checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" dependencies = [ "cfg-if 1.0.0", "log", @@ -2752,6 +2753,15 @@ dependencies = [ "leb128", ] +[[package]] +name = "wasm-encoder" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f0c17267a5ffd6ae3d897589460e21db1673c84fb7016b909c9691369a75ea" +dependencies = [ + "leb128", +] + [[package]] name = "wasm-smith" version = "0.4.5" @@ -2761,7 +2771,7 @@ dependencies = [ "arbitrary", "indexmap", "leb128", - "wasm-encoder", + "wasm-encoder 0.4.1", ] [[package]] @@ -2779,15 +2789,11 @@ dependencies = [ "thiserror", "wasm-bindgen", "wasm-bindgen-test", - "wasmer-artifact", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-llvm", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "wasmparser 0.83.0", @@ -2795,16 +2801,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -dependencies = [ - "enumset", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-bin-fuzz" version = "0.0.0" @@ -2813,11 +2809,10 @@ dependencies = [ "libfuzzer-sys", "wasm-smith", "wasmer", + "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-llvm", "wasmer-compiler-singlepass", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-middlewares", "wasmprinter", ] @@ -2838,14 +2833,11 @@ dependencies = [ "thiserror", "typetag", "wasmer", + "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-llvm", "wasmer-compiler-singlepass", "wasmer-emscripten", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-staticlib", - "wasmer-engine-universal", "wasmer-middlewares", "wasmer-types", "wasmer-wasi", @@ -2862,9 +2854,8 @@ dependencies = [ "tempfile", "thiserror", "wasmer", + "wasmer-compiler", "wasmer-compiler-singlepass", - "wasmer-engine-dylib", - "wasmer-engine-universal", ] [[package]] @@ -2889,10 +2880,6 @@ dependencies = [ "wasmer-compiler-llvm", "wasmer-compiler-singlepass", "wasmer-emscripten", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-staticlib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vfs", "wasmer-vm", @@ -2905,16 +2892,27 @@ dependencies = [ name = "wasmer-compiler" version = "2.3.0" dependencies = [ + "backtrace", + "cfg-if 1.0.0", + "enum-iterator", "enumset", "hashbrown 0.11.2", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "rkyv", + "rustc-demangle", "serde", "serde_bytes", "smallvec", "target-lexicon 0.12.4", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser 0.83.0", + "winapi", ] [[package]] @@ -2935,7 +2933,6 @@ dependencies = [ "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", - "wasmer-engine-universal-artifact", "wasmer-types", ] @@ -2972,7 +2969,7 @@ dependencies = [ "rayon", "regex", "rustc_version 0.4.0", - "semver 1.0.9", + "semver 1.0.10", "smallvec", "target-lexicon 0.12.4", "wasmer-compiler", @@ -3023,114 +3020,6 @@ dependencies = [ "wasmer", ] -[[package]] -name = "wasmer-engine" -version = "2.3.0" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon 0.12.4", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dummy" -version = "2.3.0" -dependencies = [ - "bincode", - "enumset", - "serde", - "serde_bytes", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -dependencies = [ - "cfg-if 1.0.0", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "object", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which 4.2.5", -] - -[[package]] -name = "wasmer-engine-staticlib" -version = "2.3.0" -dependencies = [ - "bincode", - "cfg-if 1.0.0", - "enumset", - "leb128", - "libloading", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -dependencies = [ - "cfg-if 1.0.0", - "enumset", - "leb128", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -dependencies = [ - "enum-iterator", - "enumset", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-integration-tests-cli" version = "2.3.0" @@ -3171,6 +3060,7 @@ dependencies = [ "more-asserts", "rkyv", "serde", + "serde_bytes", "thiserror", ] @@ -3219,7 +3109,6 @@ dependencies = [ "scopeguard", "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] @@ -3340,11 +3229,6 @@ dependencies = [ "wasmer-compiler-llvm", "wasmer-compiler-singlepass", "wasmer-emscripten", - "wasmer-engine", - "wasmer-engine-dummy", - "wasmer-engine-dylib", - "wasmer-engine-staticlib", - "wasmer-engine-universal", "wasmer-middlewares", "wasmer-types", "wasmer-wasi", @@ -3359,21 +3243,21 @@ checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" [[package]] name = "wasmparser" -version = "0.85.0" +version = "0.86.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570460c58b21e9150d2df0eaaedbb7816c34bcec009ae0dcc976e40ba81463e7" +checksum = "4bcbfe95447da2aa7ff171857fc8427513eb57c75a729bb190e974dc695e8f5c" dependencies = [ "indexmap", ] [[package]] name = "wasmprinter" -version = "0.2.35" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea454634a2a7888d053f7723a26a76024e4f705cf86f7b4d38d5f15b79369c31" +checksum = "aa4cca415278da771add7c9ab7f3391f04b8d98719d2cf28a185d38d5206697e" dependencies = [ "anyhow", - "wasmparser 0.85.0", + "wasmparser 0.86.0", ] [[package]] @@ -3396,22 +3280,23 @@ dependencies = [ [[package]] name = "wast" -version = "41.0.0" +version = "42.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f882898b8b817cc4edc16aa3692fdc087b356edc8cc0c2164f5b5181e31c3870" +checksum = "badcb03f976f983ff0daf294da9697be659442f61e6b0942bb37a2b6cbfe9dd4" dependencies = [ "leb128", "memchr", "unicode-width", + "wasm-encoder 0.13.0", ] [[package]] name = "wat" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48b3b9b3e39e66c7fd3f8be785e74444d216260f491e93369e317ed6482ff80f" +checksum = "b92f20b742ac527066c8414bc0637352661b68cab07ef42586cefaba71c965cf" dependencies = [ - "wast 41.0.0", + "wast 42.0.0", ] [[package]] @@ -3503,17 +3388,6 @@ dependencies = [ "libc", ] -[[package]] -name = "which" -version = "4.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" -dependencies = [ - "either", - "lazy_static", - "libc", -] - [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index d086b027bb7..d3564e1d60f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,15 +11,11 @@ autoexamples = false [dependencies] wasmer = { version = "=2.3.0", path = "lib/api", default-features = false } -wasmer-compiler = { version = "=2.3.0", path = "lib/compiler" } +wasmer-compiler = { version = "=2.3.0", path = "lib/compiler", features = ["universal_engine"] } wasmer-compiler-cranelift = { version = "=2.3.0", path = "lib/compiler-cranelift", optional = true } wasmer-compiler-singlepass = { version = "=2.3.0", path = "lib/compiler-singlepass", optional = true } wasmer-compiler-llvm = { version = "=2.3.0", path = "lib/compiler-llvm", optional = true } wasmer-emscripten = { version = "=2.3.0", path = "lib/emscripten", optional = true } -wasmer-engine = { version = "=2.3.0", path = "lib/engine" } -wasmer-engine-universal = { version = "=2.3.0", path = "lib/engine-universal", optional = true } -wasmer-engine-dylib = { version = "=2.3.0", path = "lib/engine-dylib", optional = true } -wasmer-engine-staticlib = { version = "=2.3.0", path = "lib/engine-staticlib", optional = true } wasmer-wasi = { version = "=2.3.0", path = "lib/wasi", optional = true } wasmer-wast = { version = "=2.3.0", path = "tests/lib/wast", optional = true } wasi-test-generator = { version = "=2.3.0", path = "tests/wasi-wast", optional = true } @@ -41,10 +37,6 @@ members = [ "lib/compiler-llvm", "lib/derive", "lib/emscripten", - "lib/engine", - "lib/engine-universal", - "lib/engine-dylib", - "lib/engine-staticlib", "lib/object", "lib/vfs", "lib/vnet", @@ -76,7 +68,6 @@ anyhow = "1.0" criterion = "0.3" lazy_static = "1.4" serial_test = "0.5" -wasmer-engine-dummy = { path = "tests/lib/engine-dummy" } compiler-test-derive = { path = "tests/lib/compiler-test-derive" } tempfile = "3.1" # For logging tests using the `RUST_LOG=debug` when testing @@ -90,27 +81,14 @@ tracing-subscriber = { version = "0.3", default-features = false, features = ["e default = [ "wat", "wast", - "universal", - "dylib", - "staticlib", "cache", "wasi", + "engine", "emscripten", "middlewares", ] -engine = [] -universal = [ - "wasmer-engine-universal", - "engine", -] -dylib = [ - "wasmer-engine-dylib", - "engine", -] -staticlib = [ - "wasmer-engine-staticlib", - "engine", -] +engine = ["universal"] +universal = [] cache = ["wasmer-cache"] wast = ["wasmer-wast"] wasi = ["wasmer-wasi"] @@ -119,9 +97,6 @@ wat = ["wasmer/wat"] compiler = [ "wasmer/compiler", "wasmer-compiler/translator", - "wasmer-engine-universal/compiler", - "wasmer-engine-dylib/compiler", - "wasmer-engine-staticlib/compiler", ] singlepass = [ "wasmer-compiler-singlepass", @@ -148,12 +123,7 @@ test-llvm = [ "llvm", ] -test-dylib = [ - "dylib", - "test-generator/test-dylib", -] test-universal = [ - "universal", "test-generator/test-universal", ] @@ -178,11 +148,6 @@ name = "engine-universal" path = "examples/engine_universal.rs" required-features = ["cranelift"] -[[example]] -name = "engine-dylib" -path = "examples/engine_dylib.rs" -required-features = ["cranelift"] - [[example]] name = "engine-headless" path = "examples/engine_headless.rs" diff --git a/Makefile b/Makefile index 4642989bf07..d7678a313f5 100644 --- a/Makefile +++ b/Makefile @@ -13,29 +13,20 @@ SHELL=/usr/bin/env bash # | Compiler ⨯ Engine ⨯ Platform ⨯ Architecture ⨯ libc | # |------------|-----------|----------|--------------|-------| # | Cranelift | Universal | Linux | amd64 | glibc | -# | LLVM | Dylib | Darwin | aarch64 | musl | -# | Singlepass | Staticlib | Windows | | | +# | LLVM | | Darwin | aarch64 | musl | +# | Singlepass | | Windows | | | # |------------|-----------|----------|--------------|-------| # # Here is what works and what doesn't: # # * Cranelift with the Universal engine works everywhere, # -# * Cranelift with the Dylib engine works on Linux+Darwin/`amd64`, but -# it doesn't work on */`aarch64` or Windows/*. -# # * LLVM with the Universal engine works on Linux+Darwin/`amd64`, # but it doesn't work on */`aarch64` or Windows/*. # -# * LLVM with the Dylib engine works on -# Linux+Darwin/`amd64`+`aarch64`, but it doesn't work on Windows/*. -# # * Singlepass with the Universal engine works on Linux+Darwin/`amd64`, but # it doesn't work on */`aarch64` or Windows/*. # -# * Singlepass with the Dylib engine doesn't work because it doesn't -# know how to output object files for the moment. -# # * Windows isn't tested on `aarch64`, that's why we consider it's not # working, but it might possibly be. @@ -217,18 +208,6 @@ compilers_engines := ifeq ($(ENABLE_CRANELIFT), 1) compilers_engines += cranelift-universal - - ifneq (, $(filter 1, $(IS_WINDOWS) $(IS_DARWIN) $(IS_LINUX))) - ifeq ($(IS_AMD64), 1) - ifneq ($(LIBC), musl) - compilers_engines += cranelift-dylib - endif - else ifeq ($(IS_AARCH64), 1) - ifneq ($(LIBC), musl) - compilers_engines += cranelift-dylib - endif - endif - endif endif ## @@ -239,10 +218,8 @@ ifeq ($(ENABLE_LLVM), 1) ifneq (, $(filter 1, $(IS_WINDOWS) $(IS_DARWIN) $(IS_LINUX))) ifeq ($(IS_AMD64), 1) compilers_engines += llvm-universal - compilers_engines += llvm-dylib else ifeq ($(IS_AARCH64), 1) compilers_engines += llvm-universal - compilers_engines += llvm-dylib endif endif endif @@ -284,7 +261,7 @@ capi_compilers_engines_exclude := # LLVM for the moment because it causes the linker to fail since LLVM is not statically linked. # TODO: Reenable LLVM in C-API capi_compiler_features := --features $(subst $(space),$(comma),$(filter-out llvm, $(compilers))) -capi_compilers_engines_exclude += llvm-universal llvm-dylib +capi_compilers_engines_exclude += llvm-universal # We exclude singlepass-universal because it doesn't support multivalue (required in wasm-c-api tests) capi_compilers_engines_exclude += singlepass-universal @@ -382,7 +359,7 @@ check-wasmer-wasm: check-capi: capi-setup RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) check $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml \ - --no-default-features --features wat,universal,dylib,staticlib,wasi,middlewares $(capi_compiler_features) + --no-default-features --features wat,universal,wasi,middlewares $(capi_compiler_features) build-wasmer: $(CARGO_BINARY) build $(CARGO_TARGET) --release --manifest-path lib/cli/Cargo.toml $(compiler_features) --bin wasmer @@ -444,82 +421,50 @@ build-docs-capi: capi-setup # when generating the documentation, we rename it to its # crate's name. Then we restore the lib's name. sed "$(SEDI)" -e 's/name = "wasmer" # ##lib.name##/name = "wasmer_c_api" # ##lib.name##/' lib/c-api/Cargo.toml - RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) doc $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --no-deps --features wat,universal,staticlib,dylib,cranelift,wasi + RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) doc $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --no-deps --features wat,universal,cranelift,wasi sed "$(SEDI)" -e 's/name = "wasmer_c_api" # ##lib.name##/name = "wasmer" # ##lib.name##/' lib/c-api/Cargo.toml build-capi: capi-setup RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features wat,universal,dylib,staticlib,wasi,middlewares $(capi_compiler_features) + --no-default-features --features wat,universal,wasi,middlewares $(capi_compiler_features) build-capi-singlepass: capi-setup RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features wat,universal,dylib,staticlib,singlepass,wasi,middlewares + --no-default-features --features wat,universal,singlepass,wasi,middlewares build-capi-singlepass-universal: capi-setup RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ --no-default-features --features wat,universal,singlepass,wasi,middlewares -build-capi-singlepass-dylib: capi-setup - RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features wat,dylib,singlepass,wasi,middlewares - -build-capi-singlepass-staticlib: capi-setup - RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features wat,staticlib,singlepass,wasi,middlewares - build-capi-cranelift: capi-setup RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features wat,universal,dylib,staticlib,cranelift,wasi,middlewares + --no-default-features --features wat,universal,cranelift,wasi,middlewares build-capi-cranelift-universal: capi-setup RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ --no-default-features --features wat,universal,cranelift,wasi,middlewares -build-capi-cranelift-dylib: capi-setup - RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features wat,dylib,cranelift,wasi,middlewares - -build-capi-cranelift-staticlib: capi-setup - RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features wat,dylib,staticlib,cranelift,wasi,middlewares - build-capi-llvm: capi-setup RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features wat,universal,dylib,staticlib,llvm,wasi,middlewares + --no-default-features --features wat,universal,llvm,wasi,middlewares build-capi-llvm-universal: capi-setup RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ --no-default-features --features wat,universal,llvm,wasi,middlewares -build-capi-llvm-dylib: capi-setup - RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features wat,dylib,llvm,wasi,middlewares - -build-capi-llvm-staticlib: capi-setup - RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features wat,staticlib,llvm,wasi,middlewares - # Headless (we include the minimal to be able to run) build-capi-headless-universal: capi-setup RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ --no-default-features --features universal,wasi -build-capi-headless-dylib: capi-setup - RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features dylib,wasi - -build-capi-headless-staticlib: capi-setup - RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features staticlib,wasi - build-capi-headless-all: capi-setup RUSTFLAGS="${RUSTFLAGS}" $(CARGO_BINARY) build $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features universal,dylib,staticlib,wasi + --no-default-features --features universal,wasi build-capi-headless-ios: capi-setup RUSTFLAGS="${RUSTFLAGS}" cargo lipo --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features dylib,wasi + --no-default-features --features wasi ##### # @@ -554,21 +499,12 @@ test-js-wasi: test-compilers-compat: $(foreach compiler,$(compilers),test-$(compiler)) -test-singlepass-dylib: - $(CARGO_BINARY) test $(CARGO_TARGET) --release --tests $(compiler_features) -- singlepass::dylib - test-singlepass-universal: $(CARGO_BINARY) test $(CARGO_TARGET) --release --tests $(compiler_features) -- singlepass::universal -test-cranelift-dylib: - $(CARGO_BINARY) test $(CARGO_TARGET) --release --tests $(compiler_features) -- cranelift::dylib - test-cranelift-universal: $(CARGO_BINARY) test $(CARGO_TARGET) --release --tests $(compiler_features) -- cranelift::universal -test-llvm-dylib: - $(CARGO_BINARY) test $(CARGO_TARGET) --release --tests $(compiler_features) -- llvm::dylib - test-llvm-universal: $(CARGO_BINARY) test $(CARGO_TARGET) --release --tests $(compiler_features) -- llvm::universal @@ -584,7 +520,7 @@ test-capi: build-capi package-capi $(foreach compiler_engine,$(capi_compilers_en test-capi-crate-%: WASMER_CAPI_CONFIG=$(shell echo $@ | sed -e s/test-capi-crate-//) $(CARGO_BINARY) test $(CARGO_TARGET) --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features wat,universal,dylib,staticlib,wasi,middlewares $(capi_compiler_features) -- --nocapture + --no-default-features --features wat,universal,wasi,middlewares $(capi_compiler_features) -- --nocapture test-capi-integration-%: # Test the Wasmer C API tests for C @@ -710,7 +646,7 @@ endif DESTDIR ?= /usr/local -install: install-wasmer install-capi-headers install-capi-lib install-capi-staticlib install-pkgconfig install-misc +install: install-wasmer install-capi-headers install-capi-lib install-pkgconfig install-misc install-wasmer: install -Dm755 target/release/wasmer $(DESTDIR)/bin/wasmer @@ -729,9 +665,6 @@ install-capi-lib: ln -sf "libwasmer.so.$$pkgver" "$(DESTDIR)/lib/libwasmer.so.$$majorver" && \ ln -sf "libwasmer.so.$$pkgver" "$(DESTDIR)/lib/libwasmer.so" -install-capi-staticlib: - install -Dm644 target/release/libwasmer.a "$(DESTDIR)/lib/libwasmer.a" - install-misc: install -Dm644 LICENSE "$(DESTDIR)"/share/licenses/wasmer/LICENSE diff --git a/benches/static_and_dynamic_functions.rs b/benches/static_and_dynamic_functions.rs index f798d9a3e57..bc61ab3c4e8 100644 --- a/benches/static_and_dynamic_functions.rs +++ b/benches/static_and_dynamic_functions.rs @@ -149,21 +149,24 @@ pub fn run_basic_dynamic_function(store: &Store, compiler_name: &str, c: &mut Cr fn run_static_benchmarks(_c: &mut Criterion) { #[cfg(feature = "llvm")] { - let store = Store::new(&Universal::new(wasmer_compiler_llvm::LLVM::new()).engine()); + let store = + Store::new_with_engine(&Universal::new(wasmer_compiler_llvm::LLVM::new()).engine()); run_basic_static_function(&store, "llvm", c); } #[cfg(feature = "cranelift")] { - let store = - Store::new(&Universal::new(wasmer_compiler_cranelift::Cranelift::new()).engine()); + let store = Store::new_with_engine( + &Universal::new(wasmer_compiler_cranelift::Cranelift::new()).engine(), + ); run_basic_static_function(&store, "cranelift", c); } #[cfg(feature = "singlepass")] { - let store = - Store::new(&Universal::new(wasmer_compiler_singlepass::Singlepass::new()).engine()); + let store = Store::new_with_engine( + &Universal::new(wasmer_compiler_singlepass::Singlepass::new()).engine(), + ); run_basic_static_function(&store, "singlepass", c); } } @@ -171,21 +174,24 @@ fn run_static_benchmarks(_c: &mut Criterion) { fn run_dynamic_benchmarks(_c: &mut Criterion) { #[cfg(feature = "llvm")] { - let store = Store::new(&Universal::new(wasmer_compiler_llvm::LLVM::new()).engine()); + let store = + Store::new_with_engine(&Universal::new(wasmer_compiler_llvm::LLVM::new()).engine()); run_basic_dynamic_function(&store, "llvm", c); } #[cfg(feature = "cranelift")] { - let store = - Store::new(&Universal::new(wasmer_compiler_cranelift::Cranelift::new()).engine()); + let store = Store::new_with_engine( + &Universal::new(wasmer_compiler_cranelift::Cranelift::new()).engine(), + ); run_basic_dynamic_function(&store, "cranelift", c); } #[cfg(feature = "singlepass")] { - let store = - Store::new(&Universal::new(wasmer_compiler_singlepass::Singlepass::new()).engine()); + let store = Store::new_with_engine( + &Universal::new(wasmer_compiler_singlepass::Singlepass::new()).engine(), + ); run_basic_dynamic_function(&store, "singlepass", c); } } diff --git a/docs/deps_dedup.dot b/docs/deps_dedup.dot index a9231d309fd..d86c4ef4bd2 100644 --- a/docs/deps_dedup.dot +++ b/docs/deps_dedup.dot @@ -5,7 +5,6 @@ digraph dependencies { n1 [label="wasmer-compiler", color=orange]; n5 [label="wasmer-engine", color=orange]; n6 [label="wasmer-engine-universal", color=orange]; - n7 [label="wasmer-engine-dylib", color=orange]; n8 [label="wasmer-types", color=orange]; n9 [label="wasmer-vm", color=orange]; n10 [label="wasmer-c-api", color=orange]; @@ -29,7 +28,6 @@ digraph dependencies { color=brown; n6 [label="wasmer-engine-universal", color=orange]; - n7 [label="wasmer-engine-dylib", color=orange]; } { diff --git a/docs/deps_dedup.svg b/docs/deps_dedup.svg index 1280e3d0faf..e05f2b17e12 100644 --- a/docs/deps_dedup.svg +++ b/docs/deps_dedup.svg @@ -42,18 +42,6 @@ - - -n7 - -wasmer-engine-dylib - - - -n0->n7 - - - n2 diff --git a/docs/migration_to_3.0.0.md b/docs/migration_to_3.0.0.md index 481a123e068..310c214dc11 100644 --- a/docs/migration_to_3.0.0.md +++ b/docs/migration_to_3.0.0.md @@ -12,12 +12,14 @@ and provide examples to make migrating to the new API as simple as possible. - [Project structure](#project-structure) - [Differences](#differences) - [Managing imports](#managing-imports) + - [Engines](#engines) ## Rationale for changes in 3.0.0 This version introduces the following changes to make the Wasmer API more ergonomic and safe: 1. `ImportsObject` and the traits `Resolver`, `NamedResolver`, etc have been removed and replaced with a single simple type `Imports`. This reduces the complexity of setting up an `Instance`. The helper macro `imports!` can still be used. +2. The `Engine`s API has been simplified, Instead of the `wasmer` user choosing and setting up an engine explicitly, everything now uses the universal engine. All functionalites of the `staticlib`,`dylib` Engines should be available unless explicitly stated as unsupported. ## How to use Wasmer 3.0.0 @@ -76,11 +78,44 @@ imports2.extend(&imports); // } ``` +### Engines + +#### Before + +In Wasmer 2.0, you had to explicitly define the Engine you want to use: + +```rust +let wasm_bytes = wat2wasm( + "..".as_bytes(), +)?; + +let compiler_config = Cranelift::default(); +let engine = Universal::new(compiler_config).engine(); +let store = Store::new(&engine); +let module = Module::new(&store, wasm_bytes)?; +let instance = Instance::new(&module, &imports! {})?; +``` + +#### After + +In Wasmer 3.0, there's only the universal engine. The user can ignore the engine details when using the API: + + +```rust +let wasm_bytes = wat2wasm( + "..".as_bytes(), +)?; + +let compiler_config = Cranelift::default(); +let store = Store::new(&compiler_config); +let module = Module::new(&store, wasm_bytes)?; +let instance = Instance::new(&module, &imports! {})?; +``` + [examples]: https://docs.wasmer.io/integrations/examples [wasmer]: https://crates.io/crates/wasmer [wasmer-wasi]: https://crates.io/crates/wasmer-wasi [wasmer-emscripten]: https://crates.io/crates/wasmer-emscripten -[wasmer-engine]: https://crates.io/crates/wasmer-engine [wasmer-compiler]: https://crates.io/crates/wasmer-compiler [wasmer.io]: https://wasmer.io [wasmer-nightly]: https://github.com/wasmerio/wasmer-nightly/ diff --git a/examples/README.md b/examples/README.md index 738a10a0a3e..83d9cedcaf4 100644 --- a/examples/README.md +++ b/examples/README.md @@ -236,24 +236,7 @@ example. -2. [**Dylib engine**][engine-dylib], explains what a Dylib engine - is, and how to set it up. The example completes itself with the - compilation of the Wasm module, its instantiation, and finally, by - calling an exported function. - - _Keywords_: native, engine, shared library, dynamic library, - executable code. - -
- Execute the example - - ```shell - $ cargo run --example engine-dylib --release --features "cranelift" - ``` - -
- -3. [**Headless engines**][engine-headless], explains what a headless +2. [**Headless engines**][engine-headless], explains what a headless engine is, what problem it does solve, and what are the benefits of it. The example completes itself with the instantiation of a pre-compiled Wasm module, and finally, by calling an exported @@ -376,7 +359,6 @@ example. [hello-world]: ./hello_world.rs [engine-universal]: ./engine_universal.rs -[engine-dylib]: ./engine_dylib.rs [engine-headless]: ./engine_headless.rs [compiler-singlepass]: ./compiler_singlepass.rs [compiler-cranelift]: ./compiler_cranelift.rs diff --git a/examples/compiler_cranelift.rs b/examples/compiler_cranelift.rs index 2d7e446c8e4..f19b7ce8191 100644 --- a/examples/compiler_cranelift.rs +++ b/examples/compiler_cranelift.rs @@ -11,8 +11,8 @@ //! Ready? use wasmer::{imports, wat2wasm, Instance, Module, Store, Value}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module with the text representation. @@ -33,7 +33,7 @@ fn main() -> Result<(), Box> { let compiler = Cranelift::default(); // Create the store - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/compiler_llvm.rs b/examples/compiler_llvm.rs index f062a1c0bc6..c62a1102064 100644 --- a/examples/compiler_llvm.rs +++ b/examples/compiler_llvm.rs @@ -11,8 +11,8 @@ //! Ready? use wasmer::{imports, wat2wasm, Instance, Module, Store, Value}; +use wasmer_compiler::Universal; use wasmer_compiler_llvm::LLVM; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module with the text representation. @@ -33,7 +33,7 @@ fn main() -> Result<(), Box> { let compiler = LLVM::default(); // Create the store - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/compiler_singlepass.rs b/examples/compiler_singlepass.rs index 845b9db302c..39d12551c0d 100644 --- a/examples/compiler_singlepass.rs +++ b/examples/compiler_singlepass.rs @@ -11,8 +11,8 @@ //! Ready? use wasmer::{imports, wat2wasm, Instance, Module, Store, Value}; +use wasmer_compiler::Universal; use wasmer_compiler_singlepass::Singlepass; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module with the text representation. @@ -33,7 +33,7 @@ fn main() -> Result<(), Box> { let compiler = Singlepass::default(); // Create the store - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/early_exit.rs b/examples/early_exit.rs index 40ed664d7fd..63fbd2a0a8b 100644 --- a/examples/early_exit.rs +++ b/examples/early_exit.rs @@ -17,8 +17,8 @@ use anyhow::bail; use std::fmt; use wasmer::{imports, wat2wasm, Function, Instance, Module, Store, TypedFunction}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; // First we need to create an error type that we'll use to signal the end of execution. #[derive(Debug, Clone, Copy)] @@ -55,7 +55,7 @@ fn main() -> anyhow::Result<()> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/engine_cross_compilation.rs b/examples/engine_cross_compilation.rs index 618d24d68ff..467cb3facd5 100644 --- a/examples/engine_cross_compilation.rs +++ b/examples/engine_cross_compilation.rs @@ -20,9 +20,9 @@ use std::str::FromStr; use wasmer::{wat2wasm, Module, RuntimeError, Store}; +use wasmer_compiler::Universal; use wasmer_compiler::{CpuFeature, Target, Triple}; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_dylib::Dylib; fn main() -> Result<(), Box> { // Let's declare the Wasm module with the text representation. @@ -67,13 +67,10 @@ fn main() -> Result<(), Box> { // Define the engine that will drive everything. // - // In this case, the engine is `wasmer_engine_dylib` which means - // that a shared object is going to be generated. - // // That's where we specify the target for the compiler. // - // Use the Dylib engine. - let engine = Dylib::new(compiler_config) + // Use the Universal engine. + let engine = Universal::new(compiler_config) // Here we go. // Pass the target to the engine! The engine will share // this information with the compiler. @@ -82,7 +79,7 @@ fn main() -> Result<(), Box> { .engine(); // Create a store, that holds the engine. - let store = Store::new(&engine); + let store = Store::new_with_engine(&engine); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/engine_dylib.rs b/examples/engine_dylib.rs index 4381ea08723..53be3ee62f2 100644 --- a/examples/engine_dylib.rs +++ b/examples/engine_dylib.rs @@ -20,67 +20,71 @@ use wasmer::{imports, wat2wasm, Instance, Module, Store, Value}; use wasmer_compiler_cranelift::Cranelift; +/* use wasmer_engine_dylib::Dylib; +*/ fn main() -> Result<(), Box> { - // Let's declare the Wasm module with the text representation. - let wasm_bytes = wat2wasm( - r#" -(module - (type $sum_t (func (param i32 i32) (result i32))) - (func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32) - local.get $x - local.get $y - i32.add) - (export "sum" (func $sum_f))) -"# - .as_bytes(), - )?; + /* + // Let's declare the Wasm module with the text representation. + let wasm_bytes = wat2wasm( + r#" + (module + (type $sum_t (func (param i32 i32) (result i32))) + (func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32) + local.get $x + local.get $y + i32.add) + (export "sum" (func $sum_f))) + "# + .as_bytes(), + )?; - // Define a compiler configuration. - // - // In this situation, the compiler is - // `wasmer_compiler_cranelift`. The compiler is responsible to - // compile the Wasm module into executable code. - let compiler_config = Cranelift::default(); + // Define a compiler configuration. + // + // In this situation, the compiler is + // `wasmer_compiler_cranelift`. The compiler is responsible to + // compile the Wasm module into executable code. + let compiler_config = Cranelift::default(); - println!("Creating Dylib engine..."); - // Define the engine that will drive everything. - // - // In this case, the engine is `wasmer_engine_dylib` which means - // that a shared object is going to be generated. - let engine = Dylib::new(compiler_config).engine(); + println!("Creating Dylib engine..."); + // Define the engine that will drive everything. + // + // In this case, the engine is `wasmer_engine_dylib` which means + // that a shared object is going to be generated. + let engine = Dylib::new(compiler_config).engine(); - // Create a store, that holds the engine. - let store = Store::new(&engine); + // Create a store, that holds the engine. + let store = Store::new_with_engine(&engine); - println!("Compiling module..."); - // Here we go. - // - // Let's compile the Wasm module. It is at this step that the Wasm - // text is transformed into Wasm bytes (if necessary), and then - // compiled to executable code by the compiler, which is then - // stored into a shared object by the engine. - let module = Module::new(&store, wasm_bytes)?; + println!("Compiling module..."); + // Here we go. + // + // Let's compile the Wasm module. It is at this step that the Wasm + // text is transformed into Wasm bytes (if necessary), and then + // compiled to executable code by the compiler, which is then + // stored into a shared object by the engine. + let module = Module::new(&store, wasm_bytes)?; - // Congrats, the Wasm module is compiled! Now let's execute it for - // the sake of having a complete example. + // Congrats, the Wasm module is compiled! Now let's execute it for + // the sake of having a complete example. - // Create an import object. Since our Wasm module didn't declare - // any imports, it's an empty object. - let import_object = imports! {}; + // Create an import object. Since our Wasm module didn't declare + // any imports, it's an empty object. + let import_object = imports! {}; - println!("Instantiating module..."); - // And here we go again. Let's instantiate the Wasm module. - let instance = Instance::new(&module, &import_object)?; + println!("Instantiating module..."); + // And here we go again. Let's instantiate the Wasm module. + let instance = Instance::new(&module, &import_object)?; - println!("Calling `sum` function..."); - // The Wasm module exports a function called `sum`. - let sum = instance.exports.get_function("sum")?; - let results = sum.call(&[Value::I32(1), Value::I32(2)])?; + println!("Calling `sum` function..."); + // The Wasm module exports a function called `sum`. + let sum = instance.exports.get_function("sum")?; + let results = sum.call(&[Value::I32(1), Value::I32(2)])?; - println!("Results: {:?}", results); - assert_eq!(results.to_vec(), vec![Value::I32(3)]); + println!("Results: {:?}", results); + assert_eq!(results.to_vec(), vec![Value::I32(3)]); + */ Ok(()) } diff --git a/examples/engine_headless.rs b/examples/engine_headless.rs index 41f8b3fcded..3c0af060e68 100644 --- a/examples/engine_headless.rs +++ b/examples/engine_headless.rs @@ -8,10 +8,9 @@ //! What problem does it solve, and what does it mean? //! //! Once a Wasm module is compiled into executable code and stored -//! somewhere (e.g. in memory with the Universal engine, or in a -//! shared object file with the Dylib engine), the module can be -//! instantiated and executed. But imagine for a second the following -//! scenario: +//! somewhere (e.g. in memory with the Universal engine), the module +//! can be instantiated and executed. But imagine for a second the +//! following scenario: //! //! * Modules are compiled ahead of time, to be instantiated later //! on. @@ -52,8 +51,8 @@ use wasmer::Instance; use wasmer::Module; use wasmer::Store; use wasmer::Value; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_dylib::Dylib; fn main() -> Result<(), Box> { // First step, let's compile the Wasm module and serialize it. @@ -80,19 +79,12 @@ fn main() -> Result<(), Box> { // compile the Wasm module into executable code. let compiler_config = Cranelift::default(); - println!("Creating Dylib engine..."); + println!("Creating univesral engine..."); // Define the engine that will drive everything. - // - // In this case, the engine is `wasmer_engine_dylib` which - // means that a shared object is going to be generated. So - // when we are going to serialize the compiled Wasm module, we - // are going to store it in a file with the `.so` extension - // for example (or `.dylib`, or `.dll` depending of the - // platform). - let engine = Dylib::new(compiler_config).engine(); + let engine = Universal::new(compiler_config).engine(); // Create a store, that holds the engine. - let store = Store::new(&engine); + let store = Store::new_with_engine(&engine); println!("Compiling module..."); // Let's compile the Wasm module. @@ -110,10 +102,10 @@ fn main() -> Result<(), Box> { // Second step, deserialize the compiled Wasm module, and execute // it, for example with Wasmer without a compiler. { - println!("Creating headless Dylib engine..."); - // We create a headless Dylib engine. - let engine = Dylib::headless().engine(); - let store = Store::new(&engine); + println!("Creating headless Universal engine..."); + // We create a headless Universal engine. + let engine = Universal::headless().engine(); + let store = Store::new_with_engine(&engine); println!("Deserializing module..."); // Here we go. diff --git a/examples/engine_universal.rs b/examples/engine_universal.rs index 0d51244f9ec..530449c0df2 100644 --- a/examples/engine_universal.rs +++ b/examples/engine_universal.rs @@ -1,6 +1,6 @@ //! Defining an engine in Wasmer is one of the fundamental steps. //! -//! This example illustrates how to use the `wasmer_engine_universal`, +//! This example illustrates how to use the `wasmer_compiler`, //! aka the Universal engine. An engine applies roughly 2 steps: //! //! 1. It compiles the Wasm module bytes to executable code, through @@ -19,8 +19,8 @@ //! Ready? use wasmer::{imports, wat2wasm, Instance, Module, Store, Value}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module with the text representation. @@ -47,12 +47,12 @@ fn main() -> Result<(), Box> { println!("Creating Universal engine..."); // Define the engine that will drive everything. // - // In this case, the engine is `wasmer_engine_universal` which roughly + // In this case, the engine is `wasmer_compiler` which roughly // means that the executable code will live in memory. let engine = Universal::new(compiler_config).engine(); // Create a store, that holds the engine. - let store = Store::new(&engine); + let store = Store::new_with_engine(&engine); println!("Compiling module..."); // Here we go. diff --git a/examples/errors.rs b/examples/errors.rs index d145fd776e1..a9b2d93ed65 100644 --- a/examples/errors.rs +++ b/examples/errors.rs @@ -14,8 +14,8 @@ //! Ready? use wasmer::{imports, wat2wasm, Instance, Module, Store}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module with the text representation. @@ -39,7 +39,7 @@ fn main() -> Result<(), Box> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/exports_function.rs b/examples/exports_function.rs index f720b804367..bf873061799 100644 --- a/examples/exports_function.rs +++ b/examples/exports_function.rs @@ -18,8 +18,8 @@ //! Ready? use wasmer::{imports, wat2wasm, Instance, Module, Store, Value}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module with the text representation. @@ -40,7 +40,7 @@ fn main() -> Result<(), Box> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/exports_global.rs b/examples/exports_global.rs index 80aad13302a..3aaa1035783 100644 --- a/examples/exports_global.rs +++ b/examples/exports_global.rs @@ -16,8 +16,8 @@ //! Ready? use wasmer::{imports, wat2wasm, Instance, Module, Mutability, Store, Type, Value}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module with the text representation. @@ -38,7 +38,7 @@ fn main() -> Result<(), Box> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/exports_memory.rs b/examples/exports_memory.rs index a3ef6c8f5bd..8103c95ac09 100644 --- a/examples/exports_memory.rs +++ b/examples/exports_memory.rs @@ -12,8 +12,8 @@ //! Ready? use wasmer::{imports, wat2wasm, Instance, Module, Store, WasmPtr}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module with the text representation. @@ -37,7 +37,7 @@ fn main() -> Result<(), Box> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/features.rs b/examples/features.rs index 3812bf8b3d6..f60d24f17d1 100644 --- a/examples/features.rs +++ b/examples/features.rs @@ -11,8 +11,8 @@ //! Ready? use wasmer::{imports, wat2wasm, Features, Instance, Module, Store, Value}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> anyhow::Result<()> { // Let's declare the Wasm module with the text representation. @@ -39,7 +39,7 @@ fn main() -> anyhow::Result<()> { let engine = Universal::new(compiler).features(features); // Now, let's define the store, and compile the module. - let store = Store::new(&engine.engine()); + let store = Store::new_with_engine(&engine.engine()); let module = Module::new(&store, wasm_bytes)?; // Finally, let's instantiate the module, and execute something diff --git a/examples/hello_world.rs b/examples/hello_world.rs index e0cc73e4aeb..dba2fff8be5 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -7,8 +7,8 @@ //! ``` use wasmer::{imports, wat2wasm, Function, Instance, Module, Store, TypedFunction}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> anyhow::Result<()> { // First we create a simple Wasm program to use with Wasmer. @@ -44,7 +44,7 @@ fn main() -> anyhow::Result<()> { // However for the purposes of showing what's happening, we create a compiler // (`Cranelift`) and pass it to an engine (`Universal`). We then pass the engine to // the store and are now ready to compile and run WebAssembly! - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); // We then use our store and Wasm bytes to compile a `Module`. // A `Module` is a compiled WebAssembly module that isn't ready to execute yet. diff --git a/examples/imports_exports.rs b/examples/imports_exports.rs index a832ed8b8d3..2cde8af885b 100644 --- a/examples/imports_exports.rs +++ b/examples/imports_exports.rs @@ -19,8 +19,8 @@ use wasmer::{ imports, wat2wasm, Function, FunctionType, Global, Instance, Memory, Module, Store, Table, Type, Value, }; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module. @@ -44,7 +44,7 @@ fn main() -> Result<(), Box> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/imports_function.rs b/examples/imports_function.rs index 767e0bdd57c..919debec005 100644 --- a/examples/imports_function.rs +++ b/examples/imports_function.rs @@ -18,8 +18,8 @@ //! Ready? use wasmer::{imports, wat2wasm, Function, FunctionType, Instance, Module, Store, Type, Value}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module with the text representation. @@ -42,7 +42,7 @@ fn main() -> Result<(), Box> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/imports_function_env.rs b/examples/imports_function_env.rs index 0cb4b8ffec5..b1b534e033f 100644 --- a/examples/imports_function_env.rs +++ b/examples/imports_function_env.rs @@ -21,8 +21,8 @@ use std::sync::{Arc, Mutex}; use wasmer::{imports, wat2wasm, Function, Instance, Module, Store, WasmerEnv}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module with the text representation. @@ -49,7 +49,7 @@ fn main() -> Result<(), Box> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/imports_global.rs b/examples/imports_global.rs index 6da88c1d8ce..af91acf83e0 100644 --- a/examples/imports_global.rs +++ b/examples/imports_global.rs @@ -16,8 +16,8 @@ //! Ready? use wasmer::{imports, wat2wasm, Global, Instance, Module, Store, Value}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module with the text representation. @@ -38,7 +38,7 @@ fn main() -> Result<(), Box> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/instance.rs b/examples/instance.rs index 1d0b16f945e..66404032e9b 100644 --- a/examples/instance.rs +++ b/examples/instance.rs @@ -15,8 +15,8 @@ //! Ready? use wasmer::{imports, wat2wasm, Instance, Module, Store}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; fn main() -> Result<(), Box> { // Let's declare the Wasm module. @@ -39,7 +39,7 @@ fn main() -> Result<(), Box> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/memory.rs b/examples/memory.rs index 5598271ed59..b664a6660e6 100644 --- a/examples/memory.rs +++ b/examples/memory.rs @@ -16,8 +16,8 @@ use std::mem; use wasmer::{imports, wat2wasm, Bytes, Instance, Module, Pages, Store, TypedFunction}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; // this example is a work in progress: // TODO: clean it up and comment it https://github.com/wasmerio/wasmer/issues/1749 @@ -57,7 +57,7 @@ fn main() -> anyhow::Result<()> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/metering.rs b/examples/metering.rs index 8e715c1f7f1..27d7248409f 100644 --- a/examples/metering.rs +++ b/examples/metering.rs @@ -19,8 +19,8 @@ use std::sync::Arc; use wasmer::wasmparser::Operator; use wasmer::CompilerConfig; use wasmer::{imports, wat2wasm, Instance, Module, Store}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; use wasmer_middlewares::{ metering::{get_remaining_points, set_remaining_points, MeteringPoints}, Metering, @@ -70,7 +70,7 @@ fn main() -> anyhow::Result<()> { // // We use our previously create compiler configuration // with the Universal engine. - let store = Store::new(&Universal::new(compiler_config).engine()); + let store = Store::new_with_engine(&Universal::new(compiler_config).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/platform_ios_headless.rs b/examples/platform_ios_headless.rs index 8a6eb8028c9..c7b67adfdd6 100644 --- a/examples/platform_ios_headless.rs +++ b/examples/platform_ios_headless.rs @@ -17,49 +17,53 @@ use std::str::FromStr; use wasmer::{wat2wasm, Module, RuntimeError, Store}; use wasmer_compiler::{CpuFeature, Target, Triple}; use wasmer_compiler_cranelift::Cranelift; +/* use wasmer_engine_dylib::Dylib; +*/ fn main() -> Result<(), Box> { - // Let's declare the Wasm module with the text representation. - let wasm_bytes = wat2wasm( - r#" -(module -(type $sum_t (func (param i32 i32) (result i32))) -(func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32) -local.get $x -local.get $y -i32.add) -(export "sum" (func $sum_f))) -"# - .as_bytes(), - )?; + /* + // Let's declare the Wasm module with the text representation. + let wasm_bytes = wat2wasm( + r#" + (module + (type $sum_t (func (param i32 i32) (result i32))) + (func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32) + local.get $x + local.get $y + i32.add) + (export "sum" (func $sum_f))) + "# + .as_bytes(), + )?; - // Create a compiler for iOS - let compiler_config = Cranelift::default(); - // Change it to `x86_64-apple-ios` if you want to target the iOS simulator - let triple = Triple::from_str("aarch64-apple-ios") - .map_err(|error| RuntimeError::new(error.to_string()))?; + // Create a compiler for iOS + let compiler_config = Cranelift::default(); + // Change it to `x86_64-apple-ios` if you want to target the iOS simulator + let triple = Triple::from_str("aarch64-apple-ios") + .map_err(|error| RuntimeError::new(error.to_string()))?; - // Let's build the target. - let mut cpu_feature = CpuFeature::set(); - cpu_feature.insert(CpuFeature::from_str("sse2")?); - let target = Target::new(triple, cpu_feature); - println!("Chosen target: {:?}", target); + // Let's build the target. + let mut cpu_feature = CpuFeature::set(); + cpu_feature.insert(CpuFeature::from_str("sse2")?); + let target = Target::new(triple, cpu_feature); + println!("Chosen target: {:?}", target); - println!("Creating Dylib engine..."); - let engine = Dylib::new(compiler_config).target(target).engine(); + println!("Creating Dylib engine..."); + let engine = Dylib::new(compiler_config).target(target).engine(); - // Create a store, that holds the engine. - let store = Store::new(&engine); + // Create a store, that holds the engine. + let store = Store::new_with_engine(&engine); - println!("Compiling module..."); - // Let's compile the Wasm module. - let module = Module::new(&store, wasm_bytes)?; - // Here we go. Let's serialize the compiled Wasm module in a - // file. - println!("Serializing module..."); - let dylib_file = Path::new("./sum.dylib"); - module.serialize_to_file(dylib_file)?; + println!("Compiling module..."); + // Let's compile the Wasm module. + let module = Module::new(&store, wasm_bytes)?; + // Here we go. Let's serialize the compiled Wasm module in a + // file. + println!("Serializing module..."); + let dylib_file = Path::new("./sum.dylib"); + module.serialize_to_file(dylib_file)?; + */ Ok(()) } diff --git a/examples/table.rs b/examples/table.rs index c0bf78b4298..edad9957a9a 100644 --- a/examples/table.rs +++ b/examples/table.rs @@ -1,8 +1,8 @@ use wasmer::{ imports, wat2wasm, Function, Instance, Module, Store, TableType, Type, TypedFunction, Value, }; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; /// A function we'll call through a table. fn host_callback(arg1: i32, arg2: i32) -> i32 { @@ -51,7 +51,7 @@ fn main() -> anyhow::Result<()> { )?; // We set up our store with an engine and a compiler. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); // Then compile our Wasm. let module = Module::new(&store, wasm_bytes)?; let import_object = imports! {}; diff --git a/examples/tunables_limit_memory.rs b/examples/tunables_limit_memory.rs index 28d31450b5f..3e43cd9f7d5 100644 --- a/examples/tunables_limit_memory.rs +++ b/examples/tunables_limit_memory.rs @@ -7,8 +7,8 @@ use wasmer::{ wat2wasm, BaseTunables, Instance, Memory, MemoryType, Module, Pages, Store, TableType, Target, Tunables, }; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; /// A custom tunables that allows you to set a memory limit. /// diff --git a/examples/wasi.rs b/examples/wasi.rs index 3d24c5af60b..2b80cf7fc11 100644 --- a/examples/wasi.rs +++ b/examples/wasi.rs @@ -16,8 +16,8 @@ //! Ready? use wasmer::{Instance, Module, Store}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; use wasmer_wasi::WasiState; fn main() -> Result<(), Box> { @@ -32,7 +32,7 @@ fn main() -> Result<(), Box> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/examples/wasi_pipes.rs b/examples/wasi_pipes.rs index fa4cad6973b..c4efec10a84 100644 --- a/examples/wasi_pipes.rs +++ b/examples/wasi_pipes.rs @@ -13,8 +13,8 @@ use std::io::{Read, Write}; use wasmer::{Instance, Module, Store}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; use wasmer_wasi::{Pipe, WasiState}; fn main() -> Result<(), Box> { @@ -29,7 +29,7 @@ fn main() -> Result<(), Box> { // Note that we don't need to specify the engine/compiler if we want to use // the default provided by Wasmer. // You can use `Store::default()` for that. - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let store = Store::new_with_engine(&Universal::new(Cranelift::default()).engine()); println!("Compiling module..."); // Let's compile the Wasm module. diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index e28680e2a09..7b2ce822057 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -16,8 +16,7 @@ wasmer = { path = "../lib/api" } wasmer-compiler-cranelift = { path = "../lib/compiler-cranelift", optional = true } wasmer-compiler-llvm = { path = "../lib/compiler-llvm", optional = true } wasmer-compiler-singlepass = { path = "../lib/compiler-singlepass", optional = true } -wasmer-engine-universal = { path = "../lib/engine-universal", optional = true } -wasmer-engine-dylib = { path = "../lib/engine-dylib", optional = true } +wasmer-compiler = { path = "../lib/compiler", optional = true } wasmer-middlewares = { path = "../lib/middlewares" } wasmprinter = "0.2" @@ -25,8 +24,7 @@ wasmprinter = "0.2" cranelift = [ "wasmer-compiler-cranelift" ] llvm = [ "wasmer-compiler-llvm" ] singlepass = [ "wasmer-compiler-singlepass" ] -universal = [ "wasmer-engine-universal" ] -dylib = [ "wasmer-engine-dylib" ] +universal = [ "wasmer-compiler" ] [[bin]] name = "equivalence_universal" @@ -53,12 +51,7 @@ name = "metering" path = "fuzz_targets/metering.rs" required-features = ["universal", "cranelift"] -[[bin]] -name = "dylib_cranelift" -path = "fuzz_targets/dylib_cranelift.rs" -required-features = ["dylib", "cranelift"] - [[bin]] name = "deterministic" path = "fuzz_targets/deterministic.rs" -required-features = ["universal", "dylib", "cranelift", "llvm", "singlepass"] \ No newline at end of file +required-features = ["universal", "cranelift", "llvm", "singlepass"] diff --git a/fuzz/fuzz_targets/deterministic.rs b/fuzz/fuzz_targets/deterministic.rs index b613d5449d5..ef550804599 100644 --- a/fuzz/fuzz_targets/deterministic.rs +++ b/fuzz/fuzz_targets/deterministic.rs @@ -3,11 +3,10 @@ use libfuzzer_sys::{arbitrary, arbitrary::Arbitrary, fuzz_target}; use wasm_smith::{Config, ConfiguredModule}; use wasmer::{CompilerConfig, Engine, Module, Store}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; use wasmer_compiler_llvm::LLVM; use wasmer_compiler_singlepass::Singlepass; -use wasmer_engine_dylib::Dylib; -use wasmer_engine_universal::Universal; #[derive(Arbitrary, Debug, Default, Copy, Clone)] struct NoImportsConfig; @@ -25,7 +24,7 @@ impl Config for NoImportsConfig { } fn compile_and_compare(name: &str, engine: impl Engine, wasm: &[u8]) { - let store = Store::new(&engine); + let store = Store::new_with_engine(&engine); // compile for first time let module = Module::new(&store, wasm).unwrap(); @@ -51,11 +50,6 @@ fuzz_target!(|module: ConfiguredModule| { Universal::new(compiler.clone()).engine(), &wasm_bytes, ); - //compile_and_compare( - // "dylib-cranelift", - // Dylib::new(compiler).engine(), - // &wasm_bytes, - //); let mut compiler = LLVM::default(); compiler.canonicalize_nans(true); @@ -65,7 +59,6 @@ fuzz_target!(|module: ConfiguredModule| { Universal::new(compiler.clone()).engine(), &wasm_bytes, ); - //compile_and_compare("dylib-llvm", Dylib::new(compiler).engine(), &wasm_bytes); let compiler = Singlepass::default(); compile_and_compare( @@ -73,9 +66,4 @@ fuzz_target!(|module: ConfiguredModule| { Universal::new(compiler.clone()).engine(), &wasm_bytes, ); - //compile_and_compare( - // "dylib-singlepass", - // Dylib::new(compiler).engine(), - // &wasm_bytes, - //); }); diff --git a/fuzz/fuzz_targets/dylib_cranelift.rs b/fuzz/fuzz_targets/dylib_cranelift.rs deleted file mode 100644 index 66be05383d5..00000000000 --- a/fuzz/fuzz_targets/dylib_cranelift.rs +++ /dev/null @@ -1,64 +0,0 @@ -#![no_main] - -use libfuzzer_sys::{arbitrary, arbitrary::Arbitrary, fuzz_target}; -use wasm_smith::{Config, ConfiguredModule}; -use wasmer::{imports, Instance, Module, Store}; -use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_dylib::Dylib; - -#[derive(Arbitrary, Debug, Default, Copy, Clone)] -struct NoImportsConfig; -impl Config for NoImportsConfig { - fn max_imports(&self) -> usize { - 0 - } - fn max_memory_pages(&self) -> u32 { - // https://github.com/wasmerio/wasmer/issues/2187 - 65535 - } - fn allow_start_export(&self) -> bool { - false - } -} -#[derive(Arbitrary)] -struct WasmSmithModule(ConfiguredModule); -impl std::fmt::Debug for WasmSmithModule { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&wasmprinter::print_bytes(self.0.to_bytes()).unwrap()) - } -} - -fuzz_target!(|module: WasmSmithModule| { - let serialized = { - let wasm_bytes = module.0.to_bytes(); - - if let Ok(path) = std::env::var("DUMP_TESTCASE") { - use std::fs::File; - use std::io::Write; - let mut file = File::create(path).unwrap(); - file.write_all(&wasm_bytes).unwrap(); - return; - } - - let compiler = Cranelift::default(); - let store = Store::new(&Dylib::new(compiler).engine()); - let module = Module::new(&store, &wasm_bytes).unwrap(); - module.serialize().unwrap() - }; - - let engine = Dylib::headless().engine(); - let store = Store::new(&engine); - let module = unsafe { Module::deserialize(&store, serialized.as_slice()) }.unwrap(); - match Instance::new(&module, &imports! {}) { - Ok(_) => {} - Err(e) => { - let error_message = format!("{}", e); - if error_message.starts_with("RuntimeError: ") - && error_message.contains("out of bounds") - { - return; - } - panic!("{}", e); - } - } -}); diff --git a/fuzz/fuzz_targets/equivalence_universal.rs b/fuzz/fuzz_targets/equivalence_universal.rs index bb4e4877f63..414f78adab2 100644 --- a/fuzz/fuzz_targets/equivalence_universal.rs +++ b/fuzz/fuzz_targets/equivalence_universal.rs @@ -5,13 +5,13 @@ use anyhow::Result; use libfuzzer_sys::{arbitrary, arbitrary::Arbitrary, fuzz_target}; use wasm_smith::{Config, ConfiguredModule}; use wasmer::{imports, CompilerConfig, Instance, Module, Store, Val}; +use wasmer_compiler::Universal; #[cfg(feature = "cranelift")] use wasmer_compiler_cranelift::Cranelift; #[cfg(feature = "llvm")] use wasmer_compiler_llvm::LLVM; #[cfg(feature = "singlepass")] use wasmer_compiler_singlepass::Singlepass; -use wasmer_engine_universal::Universal; #[derive(Arbitrary, Debug, Default, Copy, Clone)] struct ExportedFunctionConfig; @@ -48,7 +48,7 @@ impl std::fmt::Debug for WasmSmithModule { #[cfg(feature = "singlepass")] fn maybe_instantiate_singlepass(wasm_bytes: &[u8]) -> Result> { let compiler = Singlepass::default(); - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); let module = Module::new(&store, &wasm_bytes); let module = match module { Ok(m) => m, @@ -69,7 +69,7 @@ fn maybe_instantiate_cranelift(wasm_bytes: &[u8]) -> Result> { let mut compiler = Cranelift::default(); compiler.canonicalize_nans(true); compiler.enable_verifier(); - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); let module = Module::new(&store, &wasm_bytes)?; let instance = Instance::new(&module, &imports! {})?; Ok(Some(instance)) @@ -80,7 +80,7 @@ fn maybe_instantiate_llvm(wasm_bytes: &[u8]) -> Result> { let mut compiler = LLVM::default(); compiler.canonicalize_nans(true); compiler.enable_verifier(); - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); let module = Module::new(&store, &wasm_bytes)?; let instance = Instance::new(&module, &imports! {})?; Ok(Some(instance)) diff --git a/fuzz/fuzz_targets/metering.rs b/fuzz/fuzz_targets/metering.rs index 69d541967cf..4f53c207cee 100644 --- a/fuzz/fuzz_targets/metering.rs +++ b/fuzz/fuzz_targets/metering.rs @@ -5,8 +5,8 @@ use std::sync::Arc; use wasm_smith::{Config, ConfiguredModule}; use wasmer::wasmparser::Operator; use wasmer::{imports, CompilerConfig, Instance, Module, Store}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; use wasmer_middlewares::Metering; #[derive(Arbitrary, Debug, Default, Copy, Clone)] @@ -56,7 +56,7 @@ fuzz_target!(|module: WasmSmithModule| { compiler.enable_verifier(); let metering = Arc::new(Metering::new(10, cost)); compiler.push_middleware(metering); - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); let module = Module::new(&store, &wasm_bytes).unwrap(); match Instance::new(&module, &imports! {}) { Ok(_) => {} diff --git a/fuzz/fuzz_targets/universal_cranelift.rs b/fuzz/fuzz_targets/universal_cranelift.rs index 05133e44289..a3642f55ed8 100644 --- a/fuzz/fuzz_targets/universal_cranelift.rs +++ b/fuzz/fuzz_targets/universal_cranelift.rs @@ -3,8 +3,8 @@ use libfuzzer_sys::{arbitrary, arbitrary::Arbitrary, fuzz_target}; use wasm_smith::{Config, ConfiguredModule}; use wasmer::{imports, CompilerConfig, Instance, Module, Store}; +use wasmer_compiler::Universal; use wasmer_compiler_cranelift::Cranelift; -use wasmer_engine_universal::Universal; #[derive(Arbitrary, Debug, Default, Copy, Clone)] struct NoImportsConfig; @@ -42,7 +42,7 @@ fuzz_target!(|module: WasmSmithModule| { let mut compiler = Cranelift::default(); compiler.canonicalize_nans(true); compiler.enable_verifier(); - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); let module = Module::new(&store, &wasm_bytes).unwrap(); match Instance::new(&module, &imports! {}) { Ok(_) => {} diff --git a/fuzz/fuzz_targets/universal_llvm.rs b/fuzz/fuzz_targets/universal_llvm.rs index 0d0044e0261..6b7d5fd127b 100644 --- a/fuzz/fuzz_targets/universal_llvm.rs +++ b/fuzz/fuzz_targets/universal_llvm.rs @@ -3,8 +3,8 @@ use libfuzzer_sys::{arbitrary, arbitrary::Arbitrary, fuzz_target}; use wasm_smith::{Config, ConfiguredModule}; use wasmer::{imports, CompilerConfig, Instance, Module, Store}; +use wasmer_compiler::Universal; use wasmer_compiler_llvm::LLVM; -use wasmer_engine_universal::Universal; #[derive(Arbitrary, Debug, Default, Copy, Clone)] struct NoImportsConfig; @@ -42,7 +42,7 @@ fuzz_target!(|module: WasmSmithModule| { let mut compiler = LLVM::default(); compiler.canonicalize_nans(true); compiler.enable_verifier(); - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); let module = Module::new(&store, &wasm_bytes).unwrap(); match Instance::new(&module, &imports! {}) { Ok(_) => {} diff --git a/fuzz/fuzz_targets/universal_singlepass.rs b/fuzz/fuzz_targets/universal_singlepass.rs index b37c81b1458..fe39c9d889c 100644 --- a/fuzz/fuzz_targets/universal_singlepass.rs +++ b/fuzz/fuzz_targets/universal_singlepass.rs @@ -3,8 +3,8 @@ use libfuzzer_sys::{arbitrary, arbitrary::Arbitrary, fuzz_target}; use wasm_smith::{Config, ConfiguredModule}; use wasmer::{imports, Instance, Module, Store}; +use wasmer_compiler::Universal; use wasmer_compiler_singlepass::Singlepass; -use wasmer_engine_universal::Universal; #[derive(Arbitrary, Debug, Default, Copy, Clone)] struct NoImportsConfig; @@ -40,7 +40,7 @@ fuzz_target!(|module: WasmSmithModule| { } let compiler = Singlepass::default(); - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); let module = Module::new(&store, &wasm_bytes); let module = match module { Ok(m) => m, diff --git a/lib/README.md b/lib/README.md index 5d917800c74..3f62bffce27 100644 --- a/lib/README.md +++ b/lib/README.md @@ -34,14 +34,6 @@ composed of a set of crates. We can group them as follows: differ: * `engine-universal` — stores the code in a custom file format, and loads it in memory, - * `engine-dylib` — stores Position-Independent Code in a native - shared object library (`.dylib`, `.so`, `.dll`) and loads it with - Operating System shared library loader (via `dlopen`), - * `engine-staticlib` — stores executable code in a native static - object library, in addition to emitting a C header file, which - both can be linked against a sandboxed WebAssembly runtime - environment for the compiled module with no need for runtime - compilation, * `object` — A library to cross-generate native objects for various platforms. * `middlewares` — A collection of middlewares, like `metering` that diff --git a/lib/api/Cargo.toml b/lib/api/Cargo.toml index fae2569337c..c88d4b5a495 100644 --- a/lib/api/Cargo.toml +++ b/lib/api/Cargo.toml @@ -22,7 +22,6 @@ edition = "2018" # Shared dependencies. [dependencies] # - Mandatory shared dependencies. -wasmer-artifact = { path = "../artifact", version = "=2.3.0" } indexmap = { version = "1.6", features = ["serde-1"] } cfg-if = "1.0" thiserror = "1.0" @@ -36,15 +35,12 @@ wat = { version = "1.0", optional = true } wasmer-vm = { path = "../vm", version = "=2.3.0" } wasmer-compiler = { path = "../compiler", version = "=2.3.0" } wasmer-derive = { path = "../derive", version = "=2.3.0" } -wasmer-engine = { path = "../engine", version = "=2.3.0" } wasmer-types = { path = "../types", version = "=2.3.0" } target-lexicon = { version = "0.12.2", default-features = false } # - Optional dependencies for `sys`. wasmer-compiler-singlepass = { path = "../compiler-singlepass", version = "=2.3.0", optional = true } wasmer-compiler-cranelift = { path = "../compiler-cranelift", version = "=2.3.0", optional = true } wasmer-compiler-llvm = { path = "../compiler-llvm", version = "=2.3.0", optional = true } -wasmer-engine-universal = { path = "../engine-universal", version = "=2.3.0", optional = true } -wasmer-engine-dylib = { path = "../engine-dylib", version = "=2.3.0", optional = true } # - Mandatory dependencies for `sys` on Windows. [target.'cfg(all(not(target_arch = "wasm32"), target_os = "windows"))'.dependencies] winapi = "0.3" @@ -92,8 +88,6 @@ sys-default = ["sys", "wat", "default-cranelift", "default-universal"] compiler = [ "sys", "wasmer-compiler/translator", - "wasmer-engine-universal/compiler", - "wasmer-engine-dylib/compiler", ] singlepass = [ "compiler", @@ -122,23 +116,14 @@ default-compiler = [] ] # - Engines. engine = ["sys"] - universal = [ - "engine", - "wasmer-engine-universal", - ] - dylib = [ - "engine", - "wasmer-engine-dylib", - ] +universal = [ + "engine", +] default-engine = [] - default-universal = [ - "default-engine", - "universal", - ] - default-dylib = [ - "default-engine", - "dylib", - ] +default-universal = [ + "default-engine", + "universal", +] # - Experimental / in-development features experimental-reference-types-extern-ref = [ "sys", @@ -146,7 +131,6 @@ experimental-reference-types-extern-ref = [ ] # - Deprecated features. jit = ["universal"] -native = ["dylib"] # Features for `js`. js = [] @@ -157,4 +141,4 @@ wasm-types-polyfill = ["js", "wasmparser"] js-serializable-module = [] [package.metadata.docs.rs] -features = ["compiler", "core", "cranelift", "default-compiler", "default-dylib", "default-engine", "dylib", "engine", "jit", "native", "singlepass", "sys", "sys-default", "universal"] +features = ["compiler", "core", "cranelift", "default-compiler", "default-engine", "engine", "jit", "native", "singlepass", "sys", "sys-default", "universal"] diff --git a/lib/api/README.md b/lib/api/README.md index c0145bc881d..07e476d9930 100644 --- a/lib/api/README.md +++ b/lib/api/README.md @@ -49,12 +49,6 @@ Wasmer is not only fast, but also designed to be *highly customizable*: compilation process and to store the generated executable code somewhere, either: * in-memory (with [`wasmer-engine-universal`]), - * in a native shared object file (with [`wasmer-engine-dylib`], - `.dylib`, `.so`, `.dll`), then load it with `dlopen`, - * in a native static object file (with [`wasmer-engine-staticlib`]), - in addition to emitting a C header file, which both can be linked - against a sandboxed WebAssembly runtime environment for the - compiled module with no need for runtime compilation. * **Pluggable compilers** — A compiler is used by an engine to transform WebAssembly into executable code: @@ -101,8 +95,6 @@ more](https://wasmerio.github.io/wasmer/crates/doc/wasmer/). Made with ❤️ by the Wasmer team, for the community [`wasmer-engine-universal`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-universal -[`wasmer-engine-dylib`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-dylib -[`wasmer-engine-staticlib`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-staticlib [`wasmer-compiler-singlepass`]: https://github.com/wasmerio/wasmer/tree/master/lib/compiler-singlepass [`wasmer-compiler-cranelift`]: https://github.com/wasmerio/wasmer/tree/master/lib/compiler-cranelift [`wasmer-compiler-llvm`]: https://github.com/wasmerio/wasmer/tree/master/lib/compiler-llvm diff --git a/lib/api/src/js/error.rs b/lib/api/src/js/error.rs index 15fdcc3a458..8931d0fd6ab 100644 --- a/lib/api/src/js/error.rs +++ b/lib/api/src/js/error.rs @@ -90,7 +90,7 @@ pub enum WasmError { /// The Serialize error can occur when serializing a /// compiled Module into a binary. -/// Copied from wasmer_engine::SerializeError +/// Copied from wasmer_compiler::SerializeError #[derive(Debug)] #[cfg_attr(feature = "std", derive(Error))] pub enum SerializeError { @@ -104,7 +104,7 @@ pub enum SerializeError { /// The Deserialize error can occur when loading a /// compiled Module from a binary. -/// Copied from wasmer_engine::DeSerializeError +/// Copied from wasmer_compiler::DeSerializeError #[derive(Error, Debug)] pub enum DeserializeError { /// An IO error diff --git a/lib/api/src/js/externals/mod.rs b/lib/api/src/js/externals/mod.rs index ebcb2b9e049..33a5bc25d2a 100644 --- a/lib/api/src/js/externals/mod.rs +++ b/lib/api/src/js/externals/mod.rs @@ -44,7 +44,7 @@ impl Extern { } } - /// Create an `Extern` from an `wasmer_engine::Export`. + /// Create an `Extern` from an `wasmer_compiler::Export`. pub fn from_vm_export(store: &Store, export: Export) -> Self { match export { Export::Function(f) => Self::Function(Function::from_vm_export(store, f)), diff --git a/lib/api/src/js/trap.rs b/lib/api/src/js/trap.rs index 88a8d6d0979..15211c7f750 100644 --- a/lib/api/src/js/trap.rs +++ b/lib/api/src/js/trap.rs @@ -53,7 +53,7 @@ impl RuntimeError { /// /// # Example /// ``` - /// let trap = wasmer_engine::RuntimeError::new("unexpected error"); + /// let trap = wasmer_compiler::RuntimeError::new("unexpected error"); /// assert_eq!("unexpected error", trap.message()); /// ``` pub fn new>(message: I) -> Self { diff --git a/lib/api/src/lib.rs b/lib/api/src/lib.rs index 2cf1dc6c20a..09f4b89150b 100644 --- a/lib/api/src/lib.rs +++ b/lib/api/src/lib.rs @@ -77,12 +77,6 @@ //! compilation process and to store the generated executable code //! somewhere, either: //! * in-memory (with [`wasmer-engine-universal`]), -//! * in a native shared object file (with [`wasmer-engine-dylib`], -//! `.dylib`, `.so`, `.dll`), then load it with `dlopen`, -//! * in a native static object file (with [`wasmer-engine-staticlib`]), -//! in addition to emitting a C header file, which both can be linked -//! against a sandboxed WebAssembly runtime environment for the -//! compiled module with no need for runtime compilation. //! //! * **Pluggable compilers** — A compiler is used by an engine to //! transform WebAssembly into executable code: @@ -324,11 +318,7 @@ //! - `universal` #![cfg_attr(feature = "universal", doc = "(enabled),")] #![cfg_attr(not(feature = "universal"), doc = "(disabled),")] -//! enables [the Universal engine][`wasmer-engine-universal`], -//! - `dylib` -#![cfg_attr(feature = "dylib", doc = "(enabled),")] -#![cfg_attr(not(feature = "dylib"), doc = "(disabled),")] -//! enables [the Dylib engine][`wasmer-engine-dylib`]. +//! enables [the Universal engine][`wasmer-engine-universal`]. //! //! The features that set defaults come in sets that are mutually exclusive. //! @@ -350,11 +340,7 @@ //! - `default-universal` #![cfg_attr(feature = "default-universal", doc = "(enabled),")] #![cfg_attr(not(feature = "default-universal"), doc = "(disabled),")] -//! set the Universal engine as the default, -//! - `default-dylib` -#![cfg_attr(feature = "default-dylib", doc = "(enabled),")] -#![cfg_attr(not(feature = "default-dylib"), doc = "(disabled),")] -//! set the Dylib engine as the default. +//! set the Universal engine as the default. //! #![cfg_attr( feature = "js", @@ -434,8 +420,6 @@ //! [`wasmer-emscripten`]: https://docs.rs/wasmer-emscripten/ //! [wasmer-engine]: https://docs.rs/wasmer-engine/ //! [`wasmer-engine-universal`]: https://docs.rs/wasmer-engine-universal/ -//! [`wasmer-engine-dylib`]: https://docs.rs/wasmer-engine-dylib/ -//! [`wasmer-engine-staticlib`]: https://docs.rs/wasmer-engine-staticlib/ //! [`wasmer-compiler-singlepass`]: https://docs.rs/wasmer-compiler-singlepass/ //! [`wasmer-compiler-llvm`]: https://docs.rs/wasmer-compiler-llvm/ //! [`wasmer-compiler-cranelift`]: https://docs.rs/wasmer-compiler-cranelift/ diff --git a/lib/api/src/sys/exports.rs b/lib/api/src/sys/exports.rs index a89fab5e88f..a613acdfcc1 100644 --- a/lib/api/src/sys/exports.rs +++ b/lib/api/src/sys/exports.rs @@ -5,7 +5,7 @@ use indexmap::IndexMap; use std::fmt; use std::iter::{ExactSizeIterator, FromIterator}; use thiserror::Error; -use wasmer_engine::Export; +use wasmer_compiler::Export; /// The `ExportError` can happen when trying to get a specific /// export [`Extern`] from the [`Instance`] exports. diff --git a/lib/api/src/sys/externals/function.rs b/lib/api/src/sys/externals/function.rs index 2fbb91f456f..5f8b1eae14c 100644 --- a/lib/api/src/sys/externals/function.rs +++ b/lib/api/src/sys/externals/function.rs @@ -12,7 +12,7 @@ use std::cmp::max; use std::ffi::c_void; use std::fmt; use std::sync::Arc; -use wasmer_engine::{Export, ExportFunction, ExportFunctionMetadata}; +use wasmer_compiler::{Export, ExportFunction, ExportFunctionMetadata}; use wasmer_vm::{ on_host_stack, raise_user_trap, resume_panic, wasmer_call_trampoline, ImportInitializerFuncPtr, VMCallerCheckedAnyfunc, VMDynamicFunctionContext, VMFuncRef, VMFunction, VMFunctionBody, diff --git a/lib/api/src/sys/externals/global.rs b/lib/api/src/sys/externals/global.rs index 70854091f17..bb93e515174 100644 --- a/lib/api/src/sys/externals/global.rs +++ b/lib/api/src/sys/externals/global.rs @@ -7,7 +7,7 @@ use crate::sys::Mutability; use crate::sys::RuntimeError; use std::fmt; use std::sync::Arc; -use wasmer_engine::Export; +use wasmer_compiler::Export; use wasmer_vm::{Global as RuntimeGlobal, VMGlobal}; /// A WebAssembly `global` instance. diff --git a/lib/api/src/sys/externals/memory.rs b/lib/api/src/sys/externals/memory.rs index c5545a01a62..5bb4135d44b 100644 --- a/lib/api/src/sys/externals/memory.rs +++ b/lib/api/src/sys/externals/memory.rs @@ -8,7 +8,7 @@ use std::mem; use std::mem::MaybeUninit; use std::slice; use std::sync::Arc; -use wasmer_engine::Export; +use wasmer_compiler::Export; use wasmer_types::Pages; use wasmer_vm::{MemoryError, VMMemory}; diff --git a/lib/api/src/sys/externals/mod.rs b/lib/api/src/sys/externals/mod.rs index c0b36487d49..df58d31df56 100644 --- a/lib/api/src/sys/externals/mod.rs +++ b/lib/api/src/sys/externals/mod.rs @@ -15,7 +15,7 @@ use crate::sys::exports::{ExportError, Exportable}; use crate::sys::store::{Store, StoreObject}; use crate::sys::ExternType; use std::fmt; -use wasmer_engine::Export; +use wasmer_compiler::Export; /// An `Extern` is the runtime representation of an entity that /// can be imported or exported. @@ -44,7 +44,7 @@ impl Extern { } } - /// Create an `Extern` from an `wasmer_engine::Export`. + /// Create an `Extern` from an `wasmer_compiler::Export`. pub fn from_vm_export(store: &Store, export: Export) -> Self { match export { Export::Function(f) => Self::Function(Function::from_vm_export(store, f)), diff --git a/lib/api/src/sys/externals/table.rs b/lib/api/src/sys/externals/table.rs index a776e009eb5..d7a11013b30 100644 --- a/lib/api/src/sys/externals/table.rs +++ b/lib/api/src/sys/externals/table.rs @@ -5,7 +5,7 @@ use crate::sys::types::{Val, ValFuncRef}; use crate::sys::RuntimeError; use crate::sys::TableType; use std::sync::Arc; -use wasmer_engine::Export; +use wasmer_compiler::Export; use wasmer_vm::{Table as RuntimeTable, TableElement, VMTable}; /// A WebAssembly `table` instance. diff --git a/lib/api/src/sys/imports.rs b/lib/api/src/sys/imports.rs index b1126836fcb..9a0c94c402c 100644 --- a/lib/api/src/sys/imports.rs +++ b/lib/api/src/sys/imports.rs @@ -4,7 +4,8 @@ use crate::{Exports, Extern, Module}; use std::collections::HashMap; use std::fmt; -use wasmer_engine::{ImportError, LinkError}; +use wasmer_compiler::LinkError; +use wasmer_types::ImportError; /// All of the import data used when instantiating. /// diff --git a/lib/api/src/sys/instance.rs b/lib/api/src/sys/instance.rs index e2c560a88c3..b80f44e2261 100644 --- a/lib/api/src/sys/instance.rs +++ b/lib/api/src/sys/instance.rs @@ -69,12 +69,12 @@ pub enum InstantiationError { HostEnvInitialization(HostEnvInitError), } -impl From for InstantiationError { - fn from(other: wasmer_engine::InstantiationError) -> Self { +impl From for InstantiationError { + fn from(other: wasmer_compiler::InstantiationError) -> Self { match other { - wasmer_engine::InstantiationError::Link(e) => Self::Link(e), - wasmer_engine::InstantiationError::Start(e) => Self::Start(e), - wasmer_engine::InstantiationError::CpuFeature(e) => Self::CpuFeature(e), + wasmer_compiler::InstantiationError::Link(e) => Self::Link(e), + wasmer_compiler::InstantiationError::Start(e) => Self::Start(e), + wasmer_compiler::InstantiationError::CpuFeature(e) => Self::CpuFeature(e), } } } diff --git a/lib/api/src/sys/mod.rs b/lib/api/src/sys/mod.rs index 7b92c948842..db67e5428ff 100644 --- a/lib/api/src/sys/mod.rs +++ b/lib/api/src/sys/mod.rs @@ -48,22 +48,19 @@ pub use crate::sys::types::{Val as Value, ValType as Type}; pub use target_lexicon::{Architecture, CallingConvention, OperatingSystem, Triple, HOST}; #[cfg(feature = "compiler")] pub use wasmer_compiler::{ - wasmparser, CompilerConfig, FunctionMiddleware, MiddlewareError, MiddlewareReaderState, - ModuleMiddleware, + wasmparser, CompilerConfig, FunctionMiddleware, MiddlewareReaderState, ModuleMiddleware, }; pub use wasmer_compiler::{ - CompileError, CpuFeature, Features, ParseCpuFeatureError, Target, WasmError, WasmResult, + CpuFeature, Engine, Export, Features, FrameInfo, LinkError, RuntimeError, Target, Tunables, }; pub use wasmer_derive::ValueType; -pub use wasmer_engine::{ - DeserializeError, Engine, Export, FrameInfo, LinkError, RuntimeError, SerializeError, Tunables, -}; pub use wasmer_types::is_wasm; #[cfg(feature = "experimental-reference-types-extern-ref")] pub use wasmer_types::ExternRef; pub use wasmer_types::{ - Bytes, ExportIndex, GlobalInit, LocalFunctionIndex, Pages, ValueType, WASM_MAX_PAGES, - WASM_MIN_PAGES, WASM_PAGE_SIZE, + Bytes, CompileError, DeserializeError, ExportIndex, GlobalInit, LocalFunctionIndex, + MiddlewareError, Pages, ParseCpuFeatureError, SerializeError, ValueType, WasmError, WasmResult, + WASM_MAX_PAGES, WASM_MIN_PAGES, WASM_PAGE_SIZE, }; // TODO: should those be moved into wasmer::vm as well? @@ -96,7 +93,7 @@ If you wish to use more than one compiler, you can simply create the own store. use wasmer::{Store, Universal, Singlepass}; let engine = Universal::new(Singlepass::default()).engine(); -let store = Store::new(&engine); +let store = Store::new_with_engine(&engine); ```"# ); @@ -110,10 +107,7 @@ pub use wasmer_compiler_cranelift::{Cranelift, CraneliftOptLevel}; pub use wasmer_compiler_llvm::{LLVMOptLevel, LLVM}; #[cfg(feature = "universal")] -pub use wasmer_engine_universal::{Universal, UniversalArtifact, UniversalEngine}; - -#[cfg(feature = "dylib")] -pub use wasmer_engine_dylib::{Dylib, DylibArtifact, DylibEngine}; +pub use wasmer_compiler::{Universal, UniversalArtifact, UniversalEngine}; /// Version number of this crate. pub const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -123,11 +117,6 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION"); #[deprecated(since = "2.0.0", note = "Please use the `universal` feature instead")] pub type JIT = Universal; -/// The Deprecated Native Engine (please use `Dylib` instead) -#[cfg(feature = "native")] -#[deprecated(since = "2.0.0", note = "Please use the `native` feature instead")] -pub type Native = Dylib; - /// This type is deprecated, it has been replaced by TypedFunction. #[deprecated( since = "3.0.0", diff --git a/lib/api/src/sys/module.rs b/lib/api/src/sys/module.rs index da5460acf0c..77d69980ca1 100644 --- a/lib/api/src/sys/module.rs +++ b/lib/api/src/sys/module.rs @@ -7,11 +7,12 @@ use std::io; use std::path::Path; use std::sync::Arc; use thiserror::Error; -use wasmer_compiler::CompileError; +use wasmer_compiler::Artifact; #[cfg(feature = "wat")] -use wasmer_compiler::WasmError; -use wasmer_engine::{Artifact, DeserializeError, SerializeError}; -use wasmer_types::{ExportsIterator, ImportsIterator, ModuleInfo}; +use wasmer_types::WasmError; +use wasmer_types::{ + CompileError, DeserializeError, ExportsIterator, ImportsIterator, ModuleInfo, SerializeError, +}; use wasmer_vm::InstanceHandle; #[derive(Error, Debug)] diff --git a/lib/api/src/sys/native.rs b/lib/api/src/sys/native.rs index 3f204fc201a..8145f6d12b6 100644 --- a/lib/api/src/sys/native.rs +++ b/lib/api/src/sys/native.rs @@ -12,7 +12,7 @@ use std::marker::PhantomData; use crate::sys::externals::function::{DynamicFunction, VMDynamicFunction}; use crate::sys::{FromToNativeWasmType, Function, RuntimeError, Store, WasmTypeList}; use std::panic::{catch_unwind, AssertUnwindSafe}; -use wasmer_engine::ExportFunction; +use wasmer_compiler::ExportFunction; use wasmer_types::NativeWasmType; use wasmer_vm::{VMDynamicFunctionContext, VMFunctionBody, VMFunctionEnvironment, VMFunctionKind}; diff --git a/lib/api/src/sys/store.rs b/lib/api/src/sys/store.rs index a90d89d8100..b779587fbf1 100644 --- a/lib/api/src/sys/store.rs +++ b/lib/api/src/sys/store.rs @@ -1,9 +1,8 @@ use crate::sys::tunables::BaseTunables; use std::fmt; use std::sync::{Arc, RwLock}; -#[cfg(all(feature = "compiler", feature = "engine"))] use wasmer_compiler::CompilerConfig; -use wasmer_engine::{Engine, Tunables}; +use wasmer_compiler::{Engine, Tunables, Universal}; use wasmer_vm::{init_traps, TrapHandler, TrapHandlerFn}; /// The store represents all global state that can be manipulated by @@ -24,8 +23,14 @@ pub struct Store { } impl Store { + /// Creates a new `Store` with a specific [`CompilerConfig`]. + pub fn new(compiler_config: Box) -> Self { + let engine = Universal::new(compiler_config).engine(); + Self::new_with_tunables(&engine, BaseTunables::for_target(engine.target())) + } + /// Creates a new `Store` with a specific [`Engine`]. - pub fn new(engine: &E) -> Self + pub fn new_with_engine(engine: &E) -> Self where E: Engine + ?Sized, { @@ -119,10 +124,7 @@ impl Default for Store { fn get_engine(mut config: impl CompilerConfig + 'static) -> impl Engine + Send + Sync { cfg_if::cfg_if! { if #[cfg(feature = "default-universal")] { - wasmer_engine_universal::Universal::new(config) - .engine() - } else if #[cfg(feature = "default-dylib")] { - wasmer_engine_dylib::Dylib::new(config) + wasmer_compiler::Universal::new(config) .engine() } else { compile_error!("No default engine chosen") diff --git a/lib/api/src/sys/tunables.rs b/lib/api/src/sys/tunables.rs index 2703aedbdb5..98e82546985 100644 --- a/lib/api/src/sys/tunables.rs +++ b/lib/api/src/sys/tunables.rs @@ -2,8 +2,7 @@ use crate::sys::{MemoryType, Pages, TableType}; use std::ptr::NonNull; use std::sync::Arc; use target_lexicon::PointerWidth; -use wasmer_compiler::Target; -use wasmer_engine::Tunables; +use wasmer_compiler::{Target, Tunables}; use wasmer_vm::MemoryError; use wasmer_vm::{ LinearMemory, LinearTable, Memory, MemoryStyle, Table, TableStyle, VMMemoryDefinition, diff --git a/lib/api/src/sys/types.rs b/lib/api/src/sys/types.rs index 7ab7bca3ab8..7de09ffc57a 100644 --- a/lib/api/src/sys/types.rs +++ b/lib/api/src/sys/types.rs @@ -70,7 +70,7 @@ impl ValFuncRef for Val { .engine() .lookup_signature(item.type_index) .expect("Signature not found in store"); - let export = wasmer_engine::ExportFunction { + let export = wasmer_compiler::ExportFunction { // TODO: // figure out if we ever need a value here: need testing with complicated import patterns metadata: None, diff --git a/lib/artifact/Cargo.toml b/lib/artifact/Cargo.toml deleted file mode 100644 index 566dc22d45f..00000000000 --- a/lib/artifact/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "wasmer-artifact" -version = "2.3.0" -description = "Wasmer Artifact abstraction" -categories = ["wasm"] -keywords = ["wasm", "webassembly", "engine"] -authors = ["Wasmer Engineering Team "] -repository = "https://github.com/wasmerio/wasmer" -license = "MIT OR Apache-2.0 WITH LLVM-exception " -readme = "README.md" -edition = "2018" - -[dependencies] -wasmer-types = { path = "../types", version = "=2.3.0" } -wasmer-compiler = { path = "../compiler", version = "=2.3.0" } -thiserror = "1.0" -enumset = "1.0" - -[badges] -maintenance = { status = "actively-developed" } diff --git a/lib/artifact/README.md b/lib/artifact/README.md deleted file mode 100644 index 515aea657a9..00000000000 --- a/lib/artifact/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# `wasmer-artifact` [![Build Status](https://github.com/wasmerio/wasmer/workflows/build/badge.svg?style=flat-square)](https://github.com/wasmerio/wasmer/actions?query=workflow%3Abuild) [![Join Wasmer Slack](https://img.shields.io/static/v1?label=Slack&message=join%20chat&color=brighgreen&style=flat-square)](https://slack.wasmer.io) [![MIT License](https://img.shields.io/github/license/wasmerio/wasmer.svg?style=flat-square)](https://github.com/wasmerio/wasmer/blob/master/LICENSE) - - -This crate is the general abstraction for creating Artifacts in Wasmer. - -### Acknowledgments - -This project borrowed some of the code of the trap implementation from -the [`wasmtime-api`], the code since then has evolved significantly. - -Please check [Wasmer `ATTRIBUTIONS`] to further see licenses and other -attributions of the project. - - -[`wasmer-engine-universal`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-universal -[`wasmer-engine-dylib`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-dylib -[`wasmer-engine-staticlib`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-staticlib -[`wasmer-engine-dummy`]: https://github.com/wasmerio/wasmer/tree/master/tests/lib/engine-dummy -[`wasmtime-api`]: https://crates.io/crates/wasmtime -[Wasmer `ATTRIBUTIONS`]: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md diff --git a/lib/artifact/src/error.rs b/lib/artifact/src/error.rs deleted file mode 100644 index 7fd6d7b6e17..00000000000 --- a/lib/artifact/src/error.rs +++ /dev/null @@ -1,66 +0,0 @@ -//! The WebAssembly possible errors -use std::io; -use thiserror::Error; -use wasmer_compiler::CompileError; -use wasmer_types::ExternType; - -/// The Serialize error can occur when serializing a -/// compiled Module into a binary. -#[derive(Error, Debug)] -pub enum SerializeError { - /// An IO error - #[error(transparent)] - Io(#[from] io::Error), - /// A generic serialization error - #[error("{0}")] - Generic(String), -} - -/// The Deserialize error can occur when loading a -/// compiled Module from a binary. -#[derive(Error, Debug)] -pub enum DeserializeError { - /// An IO error - #[error(transparent)] - Io(#[from] io::Error), - /// A generic deserialization error - #[error("{0}")] - Generic(String), - /// Incompatible serialized binary - #[error("incompatible binary: {0}")] - Incompatible(String), - /// The provided binary is corrupted - #[error("corrupted binary: {0}")] - CorruptedBinary(String), - /// The binary was valid, but we got an error when - /// trying to allocate the required resources. - #[error(transparent)] - Compiler(CompileError), -} - -/// An ImportError. -/// -/// Note: this error is not standard to WebAssembly, but it's -/// useful to determine the import issue on the API side. -#[derive(Error, Debug)] -pub enum ImportError { - /// Incompatible Import Type. - /// This error occurs when the import types mismatch. - #[error("incompatible import type. Expected {0:?} but received {1:?}")] - IncompatibleType(ExternType, ExternType), - - /// Unknown Import. - /// This error occurs when an import was expected but not provided. - #[error("unknown import. Expected {0:?}")] - UnknownImport(ExternType), -} - -/// An error while preinstantiating a module. -/// -#[derive(Error, Debug)] -pub enum PreInstantiationError { - /// The module was compiled with a CPU feature that is not available on - /// the current host. - #[error("module compiled with CPU feature that is missing from host")] - CpuFeature(String), -} diff --git a/lib/artifact/src/funcbody.rs b/lib/artifact/src/funcbody.rs deleted file mode 100644 index 662623baa83..00000000000 --- a/lib/artifact/src/funcbody.rs +++ /dev/null @@ -1,17 +0,0 @@ -/// A placeholder byte-sized type which is just used to provide some amount of type -/// safety when dealing with pointers to JIT-compiled function bodies. Note that it's -/// deliberately not Copy, as we shouldn't be carelessly copying function body bytes -/// around. -#[repr(C)] -pub struct VMFunctionBody(u8); - -#[cfg(test)] -mod test_vmfunction_body { - use super::VMFunctionBody; - use std::mem::size_of; - - #[test] - fn check_vmfunction_body_offsets() { - assert_eq!(size_of::(), 1); - } -} diff --git a/lib/artifact/src/lib.rs b/lib/artifact/src/lib.rs deleted file mode 100644 index 14784ee14e5..00000000000 --- a/lib/artifact/src/lib.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! Generic Artifact abstraction for Wasmer Engines. - -#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] -#![warn(unused_import_braces)] -#![cfg_attr( - feature = "cargo-clippy", - allow(clippy::new_without_default, clippy::new_without_default) -)] -#![cfg_attr( - feature = "cargo-clippy", - warn( - clippy::float_arithmetic, - clippy::mut_mut, - clippy::nonminimal_bool, - clippy::map_unwrap_or, - clippy::print_stdout, - clippy::unicode_not_nfc, - clippy::use_self - ) -)] - -mod artifact; -mod error; -mod funcbody; - -pub use crate::artifact::{ArtifactCreate, MetadataHeader, Upcastable}; -pub use crate::error::{DeserializeError, ImportError, PreInstantiationError, SerializeError}; -pub use crate::funcbody::VMFunctionBody; - -/// Version number of this crate. -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); - -/// A safe wrapper around `VMFunctionBody`. -#[derive(Clone, Copy, Debug)] -#[repr(transparent)] -pub struct FunctionBodyPtr(pub *const VMFunctionBody); - -impl std::ops::Deref for FunctionBodyPtr { - type Target = *const VMFunctionBody; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -/// # Safety -/// The VMFunctionBody that this points to is opaque, so there's no data to -/// read or write through this pointer. This is essentially a usize. -unsafe impl Send for FunctionBodyPtr {} -/// # Safety -/// The VMFunctionBody that this points to is opaque, so there's no data to -/// read or write through this pointer. This is essentially a usize. -unsafe impl Sync for FunctionBodyPtr {} diff --git a/lib/c-api/Cargo.toml b/lib/c-api/Cargo.toml index 6bfa4b7fbd9..1059fdb2261 100644 --- a/lib/c-api/Cargo.toml +++ b/lib/c-api/Cargo.toml @@ -27,10 +27,7 @@ wasmer-compiler-cranelift = { version = "=2.3.0", path = "../compiler-cranelift" wasmer-compiler-singlepass = { version = "=2.3.0", path = "../compiler-singlepass", optional = true } wasmer-compiler-llvm = { version = "=2.3.0", path = "../compiler-llvm", optional = true } wasmer-emscripten = { version = "=2.3.0", path = "../emscripten", optional = true } -wasmer-engine = { version = "=2.3.0", path = "../engine" } -wasmer-engine-universal = { version = "=2.3.0", path = "../engine-universal", optional = true } -wasmer-engine-dylib = { version = "=2.3.0", path = "../engine-dylib", optional = true } -wasmer-engine-staticlib = { version = "=2.3.0", path = "../engine-staticlib", optional = true } +wasmer-compiler = { version = "=2.3.0", path = "../compiler" } wasmer-middlewares = { version = "=2.3.0", path = "../middlewares", optional = true } wasmer-wasi = { version = "=2.3.0", path = "../wasi", default-features = false, features = ["host-fs", "sys"], optional = true } wasmer-types = { version = "=2.3.0", path = "../types" } @@ -57,28 +54,16 @@ default = [ ] wat = ["wasmer-api/wat"] wasi = ["wasmer-wasi"] -engine = [] middlewares = [ "compiler", "wasmer-middlewares", ] universal = [ - "wasmer-engine-universal", - "engine", -] -dylib = [ - "wasmer-engine-dylib", - "engine", -] -staticlib = [ - "wasmer-engine-staticlib", - "engine", + "wasmer-compiler/universal_engine", + "compiler", ] compiler = [ "wasmer-api/compiler", - "wasmer-engine-universal/compiler", - "wasmer-engine-dylib/compiler", - "wasmer-engine-staticlib/compiler" ] singlepass = [ "wasmer-compiler-singlepass", @@ -95,10 +80,9 @@ llvm = [ # Deprecated features. jit = ["universal"] -native = ["dylib"] # TODO: Port this feature. #emscripten = ["wasmer-emscripten"] [build-dependencies] -cbindgen = "0.19" \ No newline at end of file +cbindgen = "0.19" diff --git a/lib/c-api/src/wasm_c_api/engine.rs b/lib/c-api/src/wasm_c_api/engine.rs index 9b59eb9c8f5..b52e8201885 100644 --- a/lib/c-api/src/wasm_c_api/engine.rs +++ b/lib/c-api/src/wasm_c_api/engine.rs @@ -13,12 +13,8 @@ use crate::error::update_last_error; use cfg_if::cfg_if; use std::sync::Arc; use wasmer_api::Engine; -#[cfg(feature = "dylib")] -use wasmer_engine_dylib::Dylib; -#[cfg(feature = "staticlib")] -use wasmer_engine_staticlib::Staticlib; #[cfg(feature = "universal")] -use wasmer_engine_universal::Universal; +use wasmer_compiler::Universal; /// Kind of compilers that can be used by the engines. /// @@ -69,14 +65,6 @@ pub enum wasmer_engine_t { /// Variant to represent the Universal engine. See the /// [`wasmer_engine_universal`] Rust crate. UNIVERSAL = 0, - - /// Variant to represent the Dylib engine. See the - /// [`wasmer_engine_dylib`] Rust crate. - DYLIB = 1, - - /// Variant to represent the Staticlib engine. See the - /// [`wasmer_engine_staticlib`] Rust crate. - STATICLIB = 2, } impl Default for wasmer_engine_t { @@ -84,10 +72,6 @@ impl Default for wasmer_engine_t { cfg_if! { if #[cfg(feature = "universal")] { Self::UNIVERSAL - } else if #[cfg(feature = "dylib")] { - Self::DYLIB - } else if #[cfg(feature = "staticlib")] { - Self::STATICLIB } else { compile_error!("Please enable one of the engines") } @@ -251,10 +235,6 @@ pub extern "C" fn wasm_config_set_compiler( /// if (wasmer_is_engine_available(UNIVERSAL)) { /// wasm_config_set_engine(config, UNIVERSAL); /// } -/// // Or maybe the Dylib engine? -/// else if (wasmer_is_engine_available(DYLIB)) { -/// wasm_config_set_engine(config, DYLIB); -/// } /// // OK, let's do not specify any particular engine. /// /// // Create the engine. @@ -332,49 +312,6 @@ cfg_if! { let engine: Arc = Arc::new(Universal::headless().engine()); Box::new(wasm_engine_t { inner: engine }) } - } else if #[cfg(all(feature = "dylib", feature = "compiler"))] { - /// Creates a new Dylib engine with the default compiler. - /// - /// # Example - /// - /// See [`wasm_engine_delete`]. - /// - /// cbindgen:ignore - #[no_mangle] - pub extern "C" fn wasm_engine_new() -> Box { - let compiler_config: Box = get_default_compiler_config(); - let engine: Arc = Arc::new(Dylib::new(compiler_config).engine()); - Box::new(wasm_engine_t { inner: engine }) - } - } else if #[cfg(feature = "dylib")] { - /// Creates a new headless Dylib engine. - /// - /// # Example - /// - /// See [`wasm_engine_delete`]. - /// - /// cbindgen:ignore - #[no_mangle] - pub extern "C" fn wasm_engine_new() -> Box { - let engine: Arc = Arc::new(Dylib::headless().engine()); - Box::new(wasm_engine_t { inner: engine }) - } - } - // There are currently no uses of the Staticlib engine + compiler from the C API. - // So if we get here, we default to headless mode regardless of if `compiler` is enabled. - else if #[cfg(feature = "staticlib")] { - /// Creates a new headless Staticlib engine. - /// - /// # Example - /// - /// See [`wasm_engine_delete`]. - /// - /// cbindgen:ignore - #[no_mangle] - pub extern "C" fn wasm_engine_new() -> Box { - let engine: Arc = Arc::new(Staticlib::headless().engine()); - Box::new(wasm_engine_t { inner: engine }) - } } else { /// Creates a new unknown engine, i.e. it will panic with an error message. /// @@ -502,46 +439,6 @@ pub extern "C" fn wasm_engine_new_with_config( } } }, - wasmer_engine_t::DYLIB => { - cfg_if! { - if #[cfg(feature = "dylib")] { - let mut builder = Dylib::new(compiler_config); - - if let Some(target) = config.target { - builder = builder.target(target.inner); - } - - if let Some(features) = config.features { - builder = builder.features(features.inner); - } - - Arc::new(builder.engine()) - } else { - return return_with_error("Wasmer has not been compiled with the `dylib` feature."); - } - } - }, - wasmer_engine_t::STATICLIB => { - cfg_if! { - // There are currently no uses of the Staticlib engine + compiler from the C API. - // So we run in headless mode. - if #[cfg(feature = "staticlib")] { - let mut builder = Staticlib::headless(); - - if let Some(target) = config.target { - builder = builder.target(target.inner); - } - - if let Some(features) = config.features { - builder = builder.features(features.inner); - } - - Arc::new(builder.engine()) - } else { - return return_with_error("Wasmer has not been compiled with the `staticlib` feature."); - } - } - }, }; Some(Box::new(wasm_engine_t { inner })) } else { @@ -565,44 +462,6 @@ pub extern "C" fn wasm_engine_new_with_config( } } }, - wasmer_engine_t::DYLIB => { - cfg_if! { - if #[cfg(feature = "dylib")] { - let mut builder = Dylib::headless(); - - if let Some(target) = config.target { - builder = builder.target(target.inner); - } - - if let Some(features) = config.features { - builder = builder.features(features.inner); - } - - Arc::new(builder.engine()) - } else { - return return_with_error("Wasmer has not been compiled with the `dylib` feature."); - } - } - }, - wasmer_engine_t::STATICLIB => { - cfg_if! { - if #[cfg(feature = "staticlib")] { - let mut builder = Staticlib::headless(); - - if let Some(target) = config.target { - builder = builder.target(target.inner); - } - - if let Some(features) = config.features { - builder = builder.features(features.inner); - } - - Arc::new(builder.engine()) - } else { - return return_with_error("Wasmer has not been compiled with the `staticlib` feature."); - } - } - }, }; Some(Box::new(wasm_engine_t { inner })) } diff --git a/lib/c-api/src/wasm_c_api/store.rs b/lib/c-api/src/wasm_c_api/store.rs index f6d1d8ee51b..40d35007c10 100644 --- a/lib/c-api/src/wasm_c_api/store.rs +++ b/lib/c-api/src/wasm_c_api/store.rs @@ -17,7 +17,7 @@ pub unsafe extern "C" fn wasm_store_new( engine: Option<&wasm_engine_t>, ) -> Option> { let engine = engine?; - let store = Store::new(&*engine.inner); + let store = Store::new_with_engine(&*engine.inner); Some(Box::new(wasm_store_t { inner: store })) } diff --git a/lib/c-api/src/wasm_c_api/unstable/engine.rs b/lib/c-api/src/wasm_c_api/unstable/engine.rs index 8eada4b2c2d..e1ea2324c8c 100644 --- a/lib/c-api/src/wasm_c_api/unstable/engine.rs +++ b/lib/c-api/src/wasm_c_api/unstable/engine.rs @@ -161,12 +161,7 @@ pub extern "C" fn wasmer_is_headless() -> bool { /// compiled library. #[no_mangle] pub extern "C" fn wasmer_is_engine_available(engine: wasmer_engine_t) -> bool { - match engine { - wasmer_engine_t::UNIVERSAL if cfg!(feature = "universal") => true, - wasmer_engine_t::DYLIB if cfg!(feature = "dylib") => true, - wasmer_engine_t::STATICLIB if cfg!(feature = "staticlib") => true, - _ => false, - } + matches!(engine, wasmer_engine_t::UNIVERSAL if cfg!(feature = "universal")) } #[cfg(test)] @@ -245,15 +240,6 @@ mod tests { "0" }, ); - set_var("DYLIB", if cfg!(feature = "dylib") { "1" } else { "0" }); - set_var( - "STATICLIB", - if cfg!(feature = "staticlib") { - "1" - } else { - "0" - }, - ); (assert_c! { #include "tests/wasmer.h" @@ -261,8 +247,6 @@ mod tests { int main() { assert(wasmer_is_engine_available(UNIVERSAL) == (getenv("UNIVERSAL")[0] == '1')); - assert(wasmer_is_engine_available(DYLIB) == (getenv("DYLIB")[0] == '1')); - assert(wasmer_is_engine_available(STATICLIB) == (getenv("STATICLIB")[0] == '1')); return 0; } @@ -270,7 +254,5 @@ mod tests { .success(); remove_var("UNIVERSAL"); - remove_var("DYLIB"); - remove_var("STATICLIB"); } } diff --git a/lib/c-api/tests/wasm.h b/lib/c-api/tests/wasm.h index 4df666147a5..dcae9cf750b 100644 --- a/lib/c-api/tests/wasm.h +++ b/lib/c-api/tests/wasm.h @@ -34,9 +34,6 @@ wasm_engine_t *wasm_engine_new() { if (strcmp(wasmer_test_engine, "universal") == 0) { assert(wasmer_is_engine_available(UNIVERSAL)); wasm_config_set_engine(config, UNIVERSAL); - } else if (strcmp(wasmer_test_engine, "dylib") == 0) { - assert(wasmer_is_engine_available(DYLIB)); - wasm_config_set_engine(config, DYLIB); } else if (wasmer_test_engine) { printf("Engine %s not recognized\n", wasmer_test_engine); abort(); diff --git a/lib/cache/Cargo.toml b/lib/cache/Cargo.toml index ca4bc0beaea..319afb3042d 100644 --- a/lib/cache/Cargo.toml +++ b/lib/cache/Cargo.toml @@ -21,8 +21,7 @@ criterion = "0.3" tempfile = "3" rand = "0.8.3" wasmer-compiler-singlepass = { path = "../compiler-singlepass", version = "=2.3.0" } -wasmer-engine-universal = { path = "../engine-universal", version = "=2.3.0" } -wasmer-engine-dylib = { path = "../engine-dylib", version = "=2.3.0" } +wasmer-compiler = { path = "../compiler", version = "=2.3.0" } [features] default = ["wasmer/js-serializable-module", "filesystem"] diff --git a/lib/cache/benches/bench_filesystem_cache.rs b/lib/cache/benches/bench_filesystem_cache.rs index b7b6a712b42..2382e93ae80 100644 --- a/lib/cache/benches/bench_filesystem_cache.rs +++ b/lib/cache/benches/bench_filesystem_cache.rs @@ -6,9 +6,8 @@ use tempfile::TempDir; use wasmer::{Module, Store}; use wasmer_cache::Cache; use wasmer_cache::{FileSystemCache, Hash}; +use wasmer_compiler::Universal; use wasmer_compiler_singlepass::Singlepass; -use wasmer_engine_dylib::Dylib; -use wasmer_engine_universal::Universal; fn random_key() -> Hash { Hash::new(rand::thread_rng().gen::<[u8; 32]>()) @@ -18,7 +17,7 @@ pub fn store_cache_universal(c: &mut Criterion) { let tmp_dir = TempDir::new().unwrap(); let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap(); let compiler = Singlepass::default(); - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); let module = Module::new( &store, std::fs::read("../../lib/c-api/examples/assets/qjs.wasm").unwrap(), @@ -37,7 +36,7 @@ pub fn load_cache_universal(c: &mut Criterion) { let tmp_dir = TempDir::new().unwrap(); let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap(); let compiler = Singlepass::default(); - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); let module = Module::new( &store, std::fs::read("../../lib/c-api/examples/assets/qjs.wasm").unwrap(), @@ -55,7 +54,7 @@ pub fn store_cache_native(c: &mut Criterion) { let tmp_dir = TempDir::new().unwrap(); let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap(); let compiler = Singlepass::default(); - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); let module = Module::new( &store, std::fs::read("../../lib/c-api/examples/assets/qjs.wasm").unwrap(), @@ -74,7 +73,7 @@ pub fn load_cache_native(c: &mut Criterion) { let tmp_dir = TempDir::new().unwrap(); let mut fs_cache = FileSystemCache::new(tmp_dir.path()).unwrap(); let compiler = Singlepass::default(); - let store = Store::new(&Universal::new(compiler).engine()); + let store = Store::new_with_engine(&Universal::new(compiler).engine()); let module = Module::new( &store, std::fs::read("../../lib/c-api/examples/assets/qjs.wasm").unwrap(), diff --git a/lib/cli-compiler/Cargo.toml b/lib/cli-compiler/Cargo.toml index e887ac55df8..c6e09127994 100644 --- a/lib/cli-compiler/Cargo.toml +++ b/lib/cli-compiler/Cargo.toml @@ -18,8 +18,7 @@ path = "src/bin/wasmer_compiler.rs" doc = false [dependencies] -wasmer-engine-universal-artifact = { version = "=2.3.0", path = "../universal-artifact", features = ["compiler"] } -wasmer-compiler = { version = "=2.3.0", path = "../compiler" } +wasmer-compiler = { version = "=2.3.0", path = "../compiler", features = ["universal_engine"] } wasmer-types = { version = "=2.3.0", path = "../types" } atty = "0.2" colored = "2.0" diff --git a/lib/cli-compiler/src/commands/compile.rs b/lib/cli-compiler/src/commands/compile.rs index b6570b51a25..e4af3e42143 100644 --- a/lib/cli-compiler/src/commands/compile.rs +++ b/lib/cli-compiler/src/commands/compile.rs @@ -3,10 +3,10 @@ use crate::warning; use anyhow::{Context, Result}; use std::path::{Path, PathBuf}; use structopt::StructOpt; -use wasmer_compiler::{CompileError, CpuFeature, ModuleEnvironment, Target, Triple}; -use wasmer_engine_universal_artifact::{ArtifactCreate, UniversalArtifactBuild}; +use wasmer_compiler::{ArtifactCreate, UniversalArtifactBuild}; +use wasmer_compiler::{CpuFeature, ModuleEnvironment, Target, Triple}; use wasmer_types::entity::PrimaryMap; -use wasmer_types::{MemoryIndex, MemoryStyle, TableIndex, TableStyle}; +use wasmer_types::{CompileError, MemoryIndex, MemoryStyle, TableIndex, TableStyle}; #[derive(Debug, StructOpt)] /// The options for the `wasmer compile` subcommand @@ -43,9 +43,7 @@ impl Compile { ) -> Result<&'static str> { Ok(match engine_type { EngineType::Universal => { - wasmer_engine_universal_artifact::UniversalArtifactBuild::get_default_extension( - target_triple, - ) + wasmer_compiler::UniversalArtifactBuild::get_default_extension(target_triple) } }) } diff --git a/lib/cli-compiler/src/store.rs b/lib/cli-compiler/src/store.rs index 096e871bcba..37dc6a65197 100644 --- a/lib/cli-compiler/src/store.rs +++ b/lib/cli-compiler/src/store.rs @@ -7,8 +7,8 @@ use std::string::ToString; #[allow(unused_imports)] use std::sync::Arc; use structopt::StructOpt; +use wasmer_compiler::UniversalEngineBuilder; use wasmer_compiler::{CompilerConfig, Features, PointerWidth, Target}; -use wasmer_engine_universal_artifact::UniversalEngineBuilder; use wasmer_types::{MemoryStyle, MemoryType, Pages, TableStyle, TableType}; /// Minimul Subset of Tunable parameters for WebAssembly compilation. diff --git a/lib/cli/Cargo.toml b/lib/cli/Cargo.toml index 777147e343d..1a9ef08e683 100644 --- a/lib/cli/Cargo.toml +++ b/lib/cli/Cargo.toml @@ -26,15 +26,11 @@ required-features = ["headless"] [dependencies] wasmer = { version = "=2.3.0", path = "../api", default-features = false } -wasmer-compiler = { version = "=2.3.0", path = "../compiler" } +wasmer-compiler = { version = "=2.3.0", path = "../compiler", features = ["universal_engine", ] } wasmer-compiler-cranelift = { version = "=2.3.0", path = "../compiler-cranelift", optional = true } wasmer-compiler-singlepass = { version = "=2.3.0", path = "../compiler-singlepass", optional = true } wasmer-compiler-llvm = { version = "=2.3.0", path = "../compiler-llvm", optional = true } wasmer-emscripten = { version = "=2.3.0", path = "../emscripten", optional = true } -wasmer-engine = { version = "=2.3.0", path = "../engine" } -wasmer-engine-universal = { version = "=2.3.0", path = "../engine-universal", optional = true } -wasmer-engine-dylib = { version = "=2.3.0", path = "../engine-dylib", optional = true } -wasmer-engine-staticlib = { version = "=2.3.0", path = "../engine-staticlib", optional = true } wasmer-vm = { version = "=2.3.0", path = "../vm" } wasmer-wasi = { version = "=2.3.0", path = "../wasi", optional = true } wasmer-wasi-experimental-io-devices = { version = "=2.3.0", path = "../wasi-experimental-io-devices", optional = true } @@ -65,26 +61,10 @@ unix_mode = "0.1.3" default = [ "wat", "wast", - "universal", - "dylib", - "staticlib", "cache", "wasi", "emscripten", ] -engine = [] -universal = [ - "wasmer-engine-universal", - "engine", -] -dylib = [ - "wasmer-engine-dylib", - "engine", -] -staticlib = [ - "wasmer-engine-staticlib", - "engine", -] cache = ["wasmer-cache"] cache-blake3-pure = ["wasmer-cache/blake3-pure"] wast = ["wasmer-wast"] @@ -93,9 +73,6 @@ emscripten = ["wasmer-emscripten"] wat = ["wasmer/wat"] compiler = [ "wasmer-compiler/translator", - "wasmer-engine-universal/compiler", - "wasmer-engine-dylib/compiler", - "wasmer-engine-staticlib/compiler", ] experimental-io-devices = [ "wasmer-wasi-experimental-io-devices", @@ -116,8 +93,4 @@ llvm = [ debug = ["fern", "log", "wasmer-wasi/logging"] disable-all-logging = ["wasmer-wasi/disable-all-logging"] headless = [] -headless-minimal = ["headless", "disable-all-logging", "wasi", "dylib", "universal"] - -# Deprecated features. -jit = ["universal"] -native = ["dylib"] +headless-minimal = ["headless", "disable-all-logging", "wasi"] diff --git a/lib/cli/README.md b/lib/cli/README.md index e02ddf67bd2..e6332d4998c 100644 --- a/lib/cli/README.md +++ b/lib/cli/README.md @@ -25,8 +25,6 @@ cargo build --release --features "singlepass,cranelift" The Wasmer supports the following features: * `wat` (default): support for executing WebAssembly text files. * `wast`(default): support for running wast test files. -* `universal` (default): support for the [Universal engine]. -* `dylib` (default): support for the [Dylib engine]. * `cache` (default): support or automatically caching compiled artifacts. * `wasi` (default): support for [WASI]. * `experimental-io-devices`: support for experimental IO devices in WASI. @@ -35,8 +33,6 @@ The Wasmer supports the following features: * `cranelift`: support for the [Cranelift compiler]. * `llvm`: support for the [LLVM compiler]. -[Universal engine]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-universal/ -[Dylib engine]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-dylib/ [WASI]: https://github.com/wasmerio/wasmer/tree/master/lib/wasi/ [Emscripten]: https://github.com/wasmerio/wasmer/tree/master/lib/emscripten/ [Singlepass compiler]: https://github.com/wasmerio/wasmer/tree/master/lib/compiler-singlepass/ @@ -62,11 +58,11 @@ wasmer run myfile.wasm Compile a WebAssembly file: ```bash -wasmer compile myfile.wasm -o myfile.so --dylib +wasmer compile myfile.wasm -o myfile.wasmu ``` Run a compiled WebAssembly file (fastest): ```bash -wasmer run myfile.so +wasmer run myfile.wasmu ``` diff --git a/lib/cli/src/bin/wasmer.rs b/lib/cli/src/bin/wasmer.rs index 8f781e1f8cd..102672d8236 100644 --- a/lib/cli/src/bin/wasmer.rs +++ b/lib/cli/src/bin/wasmer.rs @@ -2,7 +2,7 @@ use wasmer_cli::cli::wasmer_main; #[cfg(not(any(feature = "cranelift", feature = "singlepass", feature = "llvm")))] compile_error!( - "Either enable at least one compiler, or compile the wasmer-headless binary instead" + "Either enable at least one compiler, or compile the wasmer-headless binary instead.\nWith cargo, you can provide a compiler option with the --features flag.\n\nExample values:\n\n\t\t--features compiler,cranelift\n\t\t--features compiler,cranelift,singlepass\n\n\n" ); fn main() { diff --git a/lib/cli/src/c_gen/mod.rs b/lib/cli/src/c_gen/mod.rs deleted file mode 100644 index 7f7417a33ba..00000000000 --- a/lib/cli/src/c_gen/mod.rs +++ /dev/null @@ -1,548 +0,0 @@ -//! A convenient little abstraction for building up C expressions and generating -//! simple C code. - -pub mod staticlib_header; - -/// An identifier in C. -pub type CIdent = String; - -/// A Type in the C language. -#[derive(Debug, Clone)] -pub enum CType { - /// C `void` type. - Void, - /// A pointer to some other type. - PointerTo { - /// Whether the pointer is `const`. - is_const: bool, - /// The type that the pointer points to. - inner: Box, - }, - /// C 8 bit unsigned integer type. - U8, - /// C 16 bit unsigned integer type. - U16, - /// C 32 bit unsigned integer type. - U32, - /// C 64 bit unsigned integer type. - U64, - /// C pointer sized unsigned integer type. - USize, - /// C 8 bit signed integer type. - I8, - /// C 16 bit signed integer type. - I16, - /// C 32 bit signed integer type. - I32, - /// C 64 bit signed integer type. - I64, - /// C pointer sized signed integer type. - ISize, - /// A function or function pointer. - Function { - /// The arguments the function takes. - arguments: Vec, - /// The return value if it has one - /// - /// None is equivalent to Some(Box(Ctype::Void)). - return_value: Option>, - }, - /// C constant array. - Array { - /// The type of the array. - inner: Box, - }, - /// A user defined type. - TypeDef(String), -} - -impl CType { - /// Convenience function to get a mutable void pointer type. - pub fn void_ptr() -> Self { - CType::PointerTo { - is_const: false, - inner: Box::new(CType::Void), - } - } - - /// Convenience function to get a const void pointer type. - #[allow(dead_code)] - pub fn const_void_ptr() -> Self { - CType::PointerTo { - is_const: true, - inner: Box::new(CType::Void), - } - } - - /// Generate the C source code for a type into the given `String`. - fn generate_c(&self, w: &mut String) { - match &self { - Self::Void => { - w.push_str("void"); - } - Self::PointerTo { is_const, inner } => { - if *is_const { - w.push_str("const "); - } - inner.generate_c(w); - w.push('*'); - } - Self::U8 => { - w.push_str("unsigned char"); - } - Self::U16 => { - w.push_str("unsigned short"); - } - Self::U32 => { - w.push_str("unsigned int"); - } - Self::U64 => { - w.push_str("unsigned long long"); - } - Self::USize => { - w.push_str("unsigned size_t"); - } - Self::I8 => { - w.push_str("char"); - } - Self::I16 => { - w.push_str("short"); - } - Self::I32 => { - w.push_str("int"); - } - Self::I64 => { - w.push_str("long long"); - } - Self::ISize => { - w.push_str("size_t"); - } - Self::Function { - arguments, - return_value, - } => { - // function with no, name, assume it's a function pointer - let ret: CType = return_value - .as_ref() - .map(|i| (**i).clone()) - .unwrap_or_default(); - ret.generate_c(w); - w.push(' '); - w.push_str("(*)"); - w.push('('); - match arguments.len() { - l if l > 1 => { - for arg in &arguments[..arguments.len() - 1] { - arg.generate_c(w); - w.push_str(", "); - } - arguments.last().unwrap().generate_c(w); - } - 1 => { - arguments[0].generate_c(w); - } - _ => {} - } - w.push(')'); - } - Self::Array { inner } => { - inner.generate_c(w); - w.push_str("[]"); - } - Self::TypeDef(inner) => { - w.push_str(inner); - } - } - } - - /// Generate the C source code for a type with a nameinto the given `String`. - fn generate_c_with_name(&self, name: &str, w: &mut String) { - match &self { - Self::PointerTo { .. } - | Self::TypeDef { .. } - | Self::Void - | Self::U8 - | Self::U16 - | Self::U32 - | Self::U64 - | Self::USize - | Self::I8 - | Self::I16 - | Self::I32 - | Self::I64 - | Self::ISize => { - self.generate_c(w); - w.push(' '); - w.push_str(name); - } - Self::Function { - arguments, - return_value, - } => { - let ret: CType = return_value - .as_ref() - .map(|i| (**i).clone()) - .unwrap_or_default(); - ret.generate_c(w); - w.push(' '); - w.push_str(name); - w.push('('); - match arguments.len() { - l if l > 1 => { - for arg in &arguments[..arguments.len() - 1] { - arg.generate_c(w); - w.push_str(", "); - } - arguments.last().unwrap().generate_c(w); - } - 1 => { - arguments[0].generate_c(w); - } - _ => {} - } - w.push(')'); - } - Self::Array { inner } => { - inner.generate_c(w); - w.push(' '); - w.push_str(name); - w.push_str("[]"); - } - } - } -} - -impl Default for CType { - fn default() -> CType { - CType::Void - } -} - -/// A statement in the C programming language. This may not be exact to what an -/// AST would look like or what the C standard says about the C language, it's -/// simply a structed way to organize data for generating C code. -#[derive(Debug, Clone)] -pub enum CStatement { - /// A declaration of some kind. - Declaration { - /// The name of the thing being declared. - name: CIdent, - /// Whether the thing being declared is `extern`. - is_extern: bool, - /// Whether the thing being declared is `const`. - is_const: bool, - /// The type of the thing being declared. - ctype: CType, - /// The definition of the thing being declared. - /// - /// This is useful for initializing constant arrays, for example. - definition: Option>, - }, - - /// A literal array of CStatements. - LiteralArray { - /// The contents of the array. - items: Vec, - }, - - /// A literal constant value, passed through directly as a string. - LiteralConstant { - /// The raw value acting as a constant. - value: String, - }, - - /// A C-style cast - Cast { - /// The type to cast to. - target_type: CType, - /// The thing being cast. - expression: Box, - }, - - /// Typedef one type to another. - TypeDef { - /// The type of the thing being typedef'd. - source_type: CType, - /// The new name by which this type may be called. - new_name: CIdent, - }, -} - -impl CStatement { - /// Generate C source code for the given CStatement. - fn generate_c(&self, w: &mut String) { - match &self { - Self::Declaration { - name, - is_extern, - is_const, - ctype, - definition, - } => { - if *is_const { - w.push_str("const "); - } - if *is_extern { - w.push_str("extern "); - } - ctype.generate_c_with_name(name, w); - if let Some(def) = definition { - w.push_str(" = "); - def.generate_c(w); - } - w.push(';'); - w.push('\n'); - } - Self::LiteralArray { items } => { - w.push('{'); - if !items.is_empty() { - w.push('\n'); - } - for item in items { - w.push('\t'); - item.generate_c(w); - w.push(','); - w.push('\n'); - } - w.push('}'); - } - Self::LiteralConstant { value } => { - w.push_str(value); - } - Self::Cast { - target_type, - expression, - } => { - w.push('('); - target_type.generate_c(w); - w.push(')'); - w.push(' '); - expression.generate_c(w); - } - Self::TypeDef { - source_type, - new_name, - } => { - w.push_str("typedef "); - // leaky abstraction / hack, doesn't fully solve the problem - if let CType::Function { .. } = source_type { - source_type.generate_c_with_name(&format!("(*{})", new_name), w); - } else { - source_type.generate_c(w); - w.push(' '); - w.push_str(new_name); - } - w.push(';'); - w.push('\n'); - } - } - } -} - -/// Generate C source code from some `CStatements` into a String. -// TODO: add config section -pub fn generate_c(statements: &[CStatement]) -> String { - let mut out = String::new(); - for statement in statements { - statement.generate_c(&mut out); - } - out -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn generate_types() { - macro_rules! assert_c_type { - ($ctype:expr, $expected:expr) => { - let mut w = String::new(); - let ctype = $ctype; - ctype.generate_c(&mut w); - assert_eq!(w, $expected); - }; - } - - assert_c_type!(CType::Void, "void"); - assert_c_type!(CType::void_ptr(), "void*"); - assert_c_type!(CType::const_void_ptr(), "const void*"); - assert_c_type!(CType::U8, "unsigned char"); - assert_c_type!(CType::U16, "unsigned short"); - assert_c_type!(CType::U32, "unsigned int"); - assert_c_type!(CType::U64, "unsigned long long"); - assert_c_type!(CType::USize, "unsigned size_t"); - assert_c_type!(CType::I8, "char"); - assert_c_type!(CType::I16, "short"); - assert_c_type!(CType::I32, "int"); - assert_c_type!(CType::I64, "long long"); - assert_c_type!(CType::ISize, "size_t"); - assert_c_type!(CType::TypeDef("my_type".to_string()), "my_type"); - assert_c_type!( - CType::Function { - arguments: vec![CType::U8, CType::ISize], - return_value: None - }, - "void (*)(unsigned char, size_t)" - ); - assert_c_type!( - CType::Function { - arguments: vec![], - return_value: Some(Box::new(CType::ISize)) - }, - "size_t (*)()" - ); - assert_c_type!( - CType::PointerTo { - is_const: true, - inner: Box::new(CType::PointerTo { - is_const: false, - inner: Box::new(CType::U32) - }) - }, - "const unsigned int**" - ); - // TODO: test more complicated const correctness rules: there are bugs relating to it. - } - - #[test] - fn generate_types_with_names() { - macro_rules! assert_c_type { - ($ctype:expr, $name:literal, $expected:expr) => { - let mut w = String::new(); - let ctype = $ctype; - ctype.generate_c_with_name($name, &mut w); - assert_eq!(w, $expected); - }; - } - - assert_c_type!(CType::Void, "main", "void main"); - assert_c_type!(CType::void_ptr(), "data", "void* data"); - assert_c_type!(CType::const_void_ptr(), "data", "const void* data"); - assert_c_type!(CType::U8, "data", "unsigned char data"); - assert_c_type!(CType::U16, "data", "unsigned short data"); - assert_c_type!(CType::U32, "data", "unsigned int data"); - assert_c_type!(CType::U64, "data", "unsigned long long data"); - assert_c_type!(CType::USize, "data", "unsigned size_t data"); - assert_c_type!(CType::I8, "data", "char data"); - assert_c_type!(CType::I16, "data", "short data"); - assert_c_type!(CType::I32, "data", "int data"); - assert_c_type!(CType::I64, "data", "long long data"); - assert_c_type!(CType::ISize, "data", "size_t data"); - assert_c_type!( - CType::TypeDef("my_type".to_string()), - "data", - "my_type data" - ); - assert_c_type!( - CType::Function { - arguments: vec![CType::U8, CType::ISize], - return_value: None - }, - "my_func", - "void my_func(unsigned char, size_t)" - ); - assert_c_type!( - CType::Function { - arguments: vec![], - return_value: Some(Box::new(CType::ISize)) - }, - "my_func", - "size_t my_func()" - ); - assert_c_type!( - CType::PointerTo { - is_const: true, - inner: Box::new(CType::PointerTo { - is_const: false, - inner: Box::new(CType::U32) - }) - }, - "data", - "const unsigned int** data" - ); - // TODO: test more complicated const correctness rules: there are bugs relating to it. - } - - #[test] - fn generate_expressions_works() { - macro_rules! assert_c_expr { - ($cexpr:expr, $expected:expr) => { - let mut w = String::new(); - let cexpr = $cexpr; - cexpr.generate_c(&mut w); - assert_eq!(w, $expected); - }; - } - - assert_c_expr!( - CStatement::LiteralConstant { - value: "\"Hello, world!\"".to_string() - }, - "\"Hello, world!\"" - ); - assert_c_expr!( - CStatement::TypeDef { - source_type: CType::Function { - arguments: vec![CType::I32, CType::I32], - return_value: None, - }, - new_name: "my_func_ptr".to_string(), - }, - "typedef void (*my_func_ptr)(int, int);\n" - ); - assert_c_expr!( - CStatement::LiteralArray { - items: vec![ - CStatement::LiteralConstant { - value: "1".to_string() - }, - CStatement::LiteralConstant { - value: "2".to_string() - }, - CStatement::LiteralConstant { - value: "3".to_string() - }, - ] - }, - "{\n\t1,\n\t2,\n\t3,\n}" - ); - assert_c_expr!(CStatement::LiteralArray { items: vec![] }, "{}"); - assert_c_expr!( - CStatement::Declaration { - name: "my_array".to_string(), - is_extern: false, - is_const: true, - ctype: CType::Array { - inner: Box::new(CType::I32) - }, - definition: Some(Box::new(CStatement::LiteralArray { - items: vec![ - CStatement::LiteralConstant { - value: "1".to_string() - }, - CStatement::LiteralConstant { - value: "2".to_string() - }, - CStatement::LiteralConstant { - value: "3".to_string() - }, - ] - })) - }, - "const int my_array[] = {\n\t1,\n\t2,\n\t3,\n};\n" - ); - assert_c_expr!( - CStatement::Declaration { - name: "my_array".to_string(), - is_extern: true, - is_const: true, - ctype: CType::Array { - inner: Box::new(CType::I32) - }, - definition: None, - }, - "const extern int my_array[];\n" - ); - } -} diff --git a/lib/cli/src/c_gen/staticlib_header.rs b/lib/cli/src/c_gen/staticlib_header.rs deleted file mode 100644 index 74747d5b4a4..00000000000 --- a/lib/cli/src/c_gen/staticlib_header.rs +++ /dev/null @@ -1,297 +0,0 @@ -//! Generate a header file for the object file produced by the Staticlib engine. - -use super::{generate_c, CStatement, CType}; -use wasmer_compiler::{Symbol, SymbolRegistry}; -use wasmer_types::ModuleInfo; - -/// Helper functions to simplify the usage of the Staticlib engine. -const HELPER_FUNCTIONS: &str = r#" -wasm_byte_vec_t generate_serialized_data() { - // We need to pass all the bytes as one big buffer so we have to do all this logic to memcpy - // the various pieces together from the generated header file. - // - // We should provide a `deseralize_vectored` function to avoid requiring this extra work. - - char* byte_ptr = (char*)&WASMER_METADATA[0]; - - size_t num_function_pointers - = sizeof(function_pointers) / sizeof(void*); - size_t num_function_trampolines - = sizeof(function_trampolines) / sizeof(void*); - size_t num_dynamic_function_trampoline_pointers - = sizeof(dynamic_function_trampoline_pointers) / sizeof(void*); - - - size_t buffer_size = module_bytes_len - + sizeof(size_t) + sizeof(function_pointers) - + sizeof(size_t) + sizeof(function_trampolines) - + sizeof(size_t) + sizeof(dynamic_function_trampoline_pointers); - - char* memory_buffer = (char*) malloc(buffer_size); - size_t current_offset = 0; - - memcpy(memory_buffer + current_offset, byte_ptr, module_bytes_len); - current_offset += module_bytes_len; - - memcpy(memory_buffer + current_offset, (void*)&num_function_pointers, sizeof(size_t)); - current_offset += sizeof(size_t); - - memcpy(memory_buffer + current_offset, (void*)&function_pointers[0], sizeof(function_pointers)); - current_offset += sizeof(function_pointers); - - memcpy(memory_buffer + current_offset, (void*)&num_function_trampolines, sizeof(size_t)); - current_offset += sizeof(size_t); - - memcpy(memory_buffer + current_offset, (void*)&function_trampolines[0], sizeof(function_trampolines)); - current_offset += sizeof(function_trampolines); - - memcpy(memory_buffer + current_offset, (void*)&num_dynamic_function_trampoline_pointers, sizeof(size_t)); - current_offset += sizeof(size_t); - - memcpy(memory_buffer + current_offset, (void*)&dynamic_function_trampoline_pointers[0], sizeof(dynamic_function_trampoline_pointers)); - current_offset += sizeof(dynamic_function_trampoline_pointers); - - wasm_byte_vec_t module_byte_vec = { - .size = buffer_size, - .data = memory_buffer, - }; - return module_byte_vec; -} - -wasm_module_t* wasmer_staticlib_engine_new(wasm_store_t* store, const char* wasm_name) { - // wasm_name intentionally unused for now: will be used in the future. - wasm_byte_vec_t module_byte_vec = generate_serialized_data(); - wasm_module_t* module = wasm_module_deserialize(store, &module_byte_vec); - free(module_byte_vec.data); - - return module; -} -"#; - -/// Generate the header file that goes with the generated object file. -pub fn generate_header_file( - module_info: &ModuleInfo, - symbol_registry: &dyn SymbolRegistry, - metadata_length: usize, -) -> String { - let mut c_statements = vec![ - CStatement::LiteralConstant { - value: "#include \n#include \n\n".to_string(), - }, - CStatement::LiteralConstant { - value: "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n".to_string(), - }, - CStatement::Declaration { - name: "module_bytes_len".to_string(), - is_extern: false, - is_const: true, - ctype: CType::U32, - definition: Some(Box::new(CStatement::LiteralConstant { - value: metadata_length.to_string(), - })), - }, - CStatement::Declaration { - name: "WASMER_METADATA".to_string(), - is_extern: true, - is_const: true, - ctype: CType::Array { - inner: Box::new(CType::U8), - }, - definition: None, - }, - ]; - let function_declarations = module_info - .functions - .iter() - .filter_map(|(f_index, sig_index)| { - Some((module_info.local_func_index(f_index)?, sig_index)) - }) - .map(|(function_local_index, _sig_index)| { - let function_name = - symbol_registry.symbol_to_name(Symbol::LocalFunction(function_local_index)); - // TODO: figure out the signature here too - CStatement::Declaration { - name: function_name, - is_extern: false, - is_const: false, - ctype: CType::Function { - arguments: vec![CType::Void], - return_value: None, - }, - definition: None, - } - }); - c_statements.push(CStatement::LiteralConstant { - value: r#" -// Compiled Wasm function pointers ordered by function index: the order they -// appeared in in the Wasm module. -"# - .to_string(), - }); - c_statements.extend(function_declarations); - - // function pointer array - { - let function_pointer_array_statements = module_info - .functions - .iter() - .filter_map(|(f_index, sig_index)| { - Some((module_info.local_func_index(f_index)?, sig_index)) - }) - .map(|(function_local_index, _sig_index)| { - let function_name = - symbol_registry.symbol_to_name(Symbol::LocalFunction(function_local_index)); - // TODO: figure out the signature here too - - CStatement::Cast { - target_type: CType::void_ptr(), - expression: Box::new(CStatement::LiteralConstant { - value: function_name, - }), - } - }) - .collect::>(); - - c_statements.push(CStatement::Declaration { - name: "function_pointers".to_string(), - is_extern: false, - is_const: true, - ctype: CType::Array { - inner: Box::new(CType::void_ptr()), - }, - definition: Some(Box::new(CStatement::LiteralArray { - items: function_pointer_array_statements, - })), - }); - } - - let func_trampoline_declarations = - module_info - .signatures - .iter() - .map(|(sig_index, _func_type)| { - let function_name = - symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index)); - - CStatement::Declaration { - name: function_name, - is_extern: false, - is_const: false, - ctype: CType::Function { - arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()], - return_value: None, - }, - definition: None, - } - }); - c_statements.push(CStatement::LiteralConstant { - value: r#" -// Trampolines (functions by which we can call into Wasm) ordered by signature. -// There is 1 trampoline per function signature in the order they appear in -// the Wasm module. -"# - .to_string(), - }); - c_statements.extend(func_trampoline_declarations); - - // function trampolines - { - let function_trampoline_statements = module_info - .signatures - .iter() - .map(|(sig_index, _vm_shared_index)| { - let function_name = - symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index)); - CStatement::LiteralConstant { - value: function_name, - } - }) - .collect::>(); - - c_statements.push(CStatement::Declaration { - name: "function_trampolines".to_string(), - is_extern: false, - is_const: true, - ctype: CType::Array { - inner: Box::new(CType::void_ptr()), - }, - definition: Some(Box::new(CStatement::LiteralArray { - items: function_trampoline_statements, - })), - }); - } - - let dyn_func_declarations = module_info - .functions - .keys() - .take(module_info.num_imported_functions) - .map(|func_index| { - let function_name = - symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index)); - // TODO: figure out the signature here - CStatement::Declaration { - name: function_name, - is_extern: false, - is_const: false, - ctype: CType::Function { - arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()], - return_value: None, - }, - definition: None, - } - }); - c_statements.push(CStatement::LiteralConstant { - value: r#" -// Dynamic trampolines are per-function and are used for each function where -// the type signature is not known statically. In this case, this corresponds to -// the imported functions. -"# - .to_string(), - }); - c_statements.extend(dyn_func_declarations); - - c_statements.push(CStatement::TypeDef { - source_type: CType::Function { - arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()], - return_value: None, - }, - new_name: "dyn_func_trampoline_t".to_string(), - }); - - // dynamic function trampoline pointer array - { - let dynamic_function_trampoline_statements = module_info - .functions - .keys() - .take(module_info.num_imported_functions) - .map(|func_index| { - let function_name = - symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index)); - CStatement::LiteralConstant { - value: function_name, - } - }) - .collect::>(); - c_statements.push(CStatement::Declaration { - name: "dynamic_function_trampoline_pointers".to_string(), - is_extern: false, - is_const: true, - ctype: CType::Array { - inner: Box::new(CType::TypeDef("dyn_func_trampoline_t".to_string())), - }, - definition: Some(Box::new(CStatement::LiteralArray { - items: dynamic_function_trampoline_statements, - })), - }); - } - - c_statements.push(CStatement::LiteralConstant { - value: HELPER_FUNCTIONS.to_string(), - }); - - c_statements.push(CStatement::LiteralConstant { - value: "\n#ifdef __cplusplus\n}\n#endif\n\n".to_string(), - }); - - generate_c(&c_statements) -} diff --git a/lib/cli/src/cli.rs b/lib/cli/src/cli.rs index f7bbb5cdf88..89b8ee971bc 100644 --- a/lib/cli/src/cli.rs +++ b/lib/cli/src/cli.rs @@ -4,8 +4,6 @@ use crate::commands::Binfmt; #[cfg(feature = "compiler")] use crate::commands::Compile; -#[cfg(all(feature = "staticlib", feature = "compiler"))] -use crate::commands::CreateExe; #[cfg(feature = "wast")] use crate::commands::Wast; use crate::commands::{Cache, Config, Inspect, Run, SelfUpdate, Validate}; @@ -46,11 +44,6 @@ enum WasmerCLIOptions { #[structopt(name = "compile")] Compile(Compile), - /// Compile a WebAssembly binary into a native executable - #[cfg(all(feature = "staticlib", feature = "compiler"))] - #[structopt(name = "create-exe")] - CreateExe(CreateExe), - /// Get various configuration information needed /// to compile programs which use Wasmer #[structopt(name = "config")] @@ -84,8 +77,6 @@ impl WasmerCLIOptions { Self::Validate(validate) => validate.execute(), #[cfg(feature = "compiler")] Self::Compile(compile) => compile.execute(), - #[cfg(all(feature = "staticlib", feature = "compiler"))] - Self::CreateExe(create_exe) => create_exe.execute(), Self::Config(config) => config.execute(), Self::Inspect(inspect) => inspect.execute(), #[cfg(feature = "wast")] diff --git a/lib/cli/src/commands.rs b/lib/cli/src/commands.rs index b0b53c05215..2757b3e02d3 100644 --- a/lib/cli/src/commands.rs +++ b/lib/cli/src/commands.rs @@ -5,8 +5,6 @@ mod cache; #[cfg(feature = "compiler")] mod compile; mod config; -#[cfg(all(feature = "staticlib", feature = "compiler"))] -mod create_exe; mod inspect; mod run; mod self_update; @@ -18,8 +16,6 @@ mod wast; pub use binfmt::*; #[cfg(feature = "compiler")] pub use compile::*; -#[cfg(all(feature = "staticlib", feature = "compiler"))] -pub use create_exe::*; #[cfg(feature = "wast")] pub use wast::*; pub use {cache::*, config::*, inspect::*, run::*, self_update::*, validate::*}; diff --git a/lib/cli/src/commands/compile.rs b/lib/cli/src/commands/compile.rs index 26b60ba8634..f3bc3b9fafb 100644 --- a/lib/cli/src/commands/compile.rs +++ b/lib/cli/src/commands/compile.rs @@ -1,4 +1,4 @@ -use crate::store::{EngineType, StoreOptions}; +use crate::store::StoreOptions; use crate::warning; use anyhow::{Context, Result}; use std::path::PathBuf; @@ -16,10 +16,6 @@ pub struct Compile { #[structopt(name = "OUTPUT PATH", short = "o", parse(from_os_str))] output: PathBuf, - /// Output path for generated header file - #[structopt(name = "HEADER PATH", long = "header", parse(from_os_str))] - header_path: Option, - /// Compilation Target triple #[structopt(long = "target")] target_triple: Option, @@ -38,28 +34,6 @@ impl Compile { .context(format!("failed to compile `{}`", self.path.display())) } - pub(crate) fn get_recommend_extension( - engine_type: &EngineType, - target_triple: &Triple, - ) -> Result<&'static str> { - Ok(match engine_type { - #[cfg(feature = "dylib")] - EngineType::Dylib => { - wasmer_engine_dylib::DylibArtifact::get_default_extension(target_triple) - } - #[cfg(feature = "universal")] - EngineType::Universal => { - wasmer_engine_universal::UniversalArtifact::get_default_extension(target_triple) - } - #[cfg(feature = "staticlib")] - EngineType::Staticlib => { - wasmer_engine_staticlib::StaticlibArtifact::get_default_extension(target_triple) - } - #[cfg(not(all(feature = "dylib", feature = "universal", feature = "staticlib")))] - _ => bail!("selected engine type is not compiled in"), - }) - } - fn inner_execute(&self) -> Result<()> { let target = self .target_triple @@ -76,14 +50,14 @@ impl Compile { Target::new(target_triple.clone(), features) }) .unwrap_or_default(); - let (store, engine_type, compiler_type) = - self.store.get_store_for_target(target.clone())?; + let (store, compiler_type) = self.store.get_store_for_target(target.clone())?; let output_filename = self .output .file_stem() .map(|osstr| osstr.to_string_lossy().to_string()) .unwrap_or_default(); - let recommended_extension = Self::get_recommend_extension(&engine_type, target.triple())?; + let recommended_extension = + wasmer_compiler::UniversalArtifact::get_default_extension(target.triple()); match self.output.extension() { Some(ext) => { if ext != recommended_extension { @@ -94,7 +68,6 @@ impl Compile { warning!("the output file has no extension. We recommend using `{}.{}` for the chosen target", &output_filename, &recommended_extension) } } - println!("Engine: {}", engine_type.to_string()); println!("Compiler: {}", compiler_type.to_string()); println!("Target: {}", target.triple()); @@ -105,43 +78,6 @@ impl Compile { self.output.display(), ); - #[cfg(feature = "staticlib")] - if engine_type == EngineType::Staticlib { - let artifact: &wasmer_engine_staticlib::StaticlibArtifact = - module.artifact().as_ref().downcast_ref().context("Engine type is Staticlib but could not downcast artifact into StaticlibArtifact")?; - let symbol_registry = artifact.symbol_registry(); - let metadata_length = artifact.metadata_length(); - let module_info = module.info(); - let header_file_src = crate::c_gen::staticlib_header::generate_header_file( - module_info, - symbol_registry, - metadata_length, - ); - - let header_path = self.header_path.as_ref().cloned().unwrap_or_else(|| { - let mut hp = PathBuf::from( - self.path - .file_stem() - .map(|fs| fs.to_string_lossy().to_string()) - .unwrap_or_else(|| "wasm_out".to_string()), - ); - hp.set_extension("h"); - hp - }); - // for C code - let mut header = std::fs::OpenOptions::new() - .create(true) - .truncate(true) - .write(true) - .open(&header_path)?; - - use std::io::Write; - header.write_all(header_file_src.as_bytes())?; - eprintln!( - "✔ Header file generated successfully at `{}`.", - header_path.display(), - ); - } Ok(()) } } diff --git a/lib/cli/src/commands/create_exe.rs b/lib/cli/src/commands/create_exe.rs deleted file mode 100644 index 960f7310e7b..00000000000 --- a/lib/cli/src/commands/create_exe.rs +++ /dev/null @@ -1,316 +0,0 @@ -//! Create a standalone native executable for a given Wasm file. - -use crate::store::{CompilerOptions, EngineType}; -use anyhow::{Context, Result}; -use std::env; -use std::fs; -use std::path::{Path, PathBuf}; -use std::process::Command; -use structopt::StructOpt; -use wasmer::*; - -const WASMER_MAIN_C_SOURCE: &[u8] = include_bytes!("wasmer_create_exe_main.c"); - -#[derive(Debug, StructOpt)] -/// The options for the `wasmer create-exe` subcommand -pub struct CreateExe { - /// Input file - #[structopt(name = "FILE", parse(from_os_str))] - path: PathBuf, - - /// Output file - #[structopt(name = "OUTPUT PATH", short = "o", parse(from_os_str))] - output: PathBuf, - - /// Compilation Target triple - #[structopt(long = "target")] - target_triple: Option, - - #[structopt(flatten)] - compiler: CompilerOptions, - - #[structopt(short = "m", multiple = true, number_of_values = 1)] - cpu_features: Vec, - - /// Additional libraries to link against. - /// This is useful for fixing linker errors that may occur on some systems. - #[structopt(short = "l", multiple = true, number_of_values = 1)] - libraries: Vec, -} - -impl CreateExe { - /// Runs logic for the `compile` subcommand - pub fn execute(&self) -> Result<()> { - let target = self - .target_triple - .as_ref() - .map(|target_triple| { - let mut features = self - .cpu_features - .clone() - .into_iter() - .fold(CpuFeature::set(), |a, b| a | b); - // Cranelift requires SSE2, so we have this "hack" for now to facilitate - // usage - features |= CpuFeature::SSE2; - Target::new(target_triple.clone(), features) - }) - .unwrap_or_default(); - let engine_type = EngineType::Staticlib; - let (store, compiler_type) = self - .compiler - .get_store_for_target_and_engine(target.clone(), engine_type)?; - - println!("Engine: {}", engine_type.to_string()); - println!("Compiler: {}", compiler_type.to_string()); - println!("Target: {}", target.triple()); - - let working_dir = tempfile::tempdir()?; - let starting_cd = env::current_dir()?; - let output_path = starting_cd.join(&self.output); - env::set_current_dir(&working_dir)?; - - #[cfg(not(windows))] - let wasm_object_path = PathBuf::from("wasm.o"); - #[cfg(windows)] - let wasm_object_path = PathBuf::from("wasm.obj"); - - let wasm_module_path = starting_cd.join(&self.path); - - let module = - Module::from_file(&store, &wasm_module_path).context("failed to compile Wasm")?; - let _ = module.serialize_to_file(&wasm_object_path)?; - - let artifact: &wasmer_engine_staticlib::StaticlibArtifact = - module.artifact().as_ref().downcast_ref().context( - "Engine type is Staticlib but could not downcast artifact into StaticlibArtifact", - )?; - let symbol_registry = artifact.symbol_registry(); - let metadata_length = artifact.metadata_length(); - let module_info = module.info(); - let header_file_src = crate::c_gen::staticlib_header::generate_header_file( - module_info, - symbol_registry, - metadata_length, - ); - - generate_header(header_file_src.as_bytes())?; - self.compile_c(wasm_object_path, output_path)?; - - eprintln!( - "✔ Native executable compiled successfully to `{}`.", - self.output.display(), - ); - - Ok(()) - } - - fn compile_c(&self, wasm_object_path: PathBuf, output_path: PathBuf) -> anyhow::Result<()> { - use std::io::Write; - - // write C src to disk - let c_src_path = Path::new("wasmer_main.c"); - #[cfg(not(windows))] - let c_src_obj = PathBuf::from("wasmer_main.o"); - #[cfg(windows)] - let c_src_obj = PathBuf::from("wasmer_main.obj"); - - { - let mut c_src_file = fs::OpenOptions::new() - .create_new(true) - .write(true) - .open(&c_src_path) - .context("Failed to open C source code file")?; - c_src_file.write_all(WASMER_MAIN_C_SOURCE)?; - } - run_c_compile(c_src_path, &c_src_obj, self.target_triple.clone()) - .context("Failed to compile C source code")?; - LinkCode { - object_paths: vec![c_src_obj, wasm_object_path], - output_path, - additional_libraries: self.libraries.clone(), - target: self.target_triple.clone(), - ..Default::default() - } - .run() - .context("Failed to link objects together")?; - - Ok(()) - } -} - -fn generate_header(header_file_src: &[u8]) -> anyhow::Result<()> { - let header_file_path = Path::new("my_wasm.h"); - let mut header = std::fs::OpenOptions::new() - .create(true) - .truncate(true) - .write(true) - .open(&header_file_path)?; - - use std::io::Write; - header.write_all(header_file_src)?; - - Ok(()) -} - -fn get_wasmer_dir() -> anyhow::Result { - Ok(PathBuf::from( - env::var("WASMER_DIR") - .or_else(|e| { - option_env!("WASMER_INSTALL_PREFIX") - .map(str::to_string) - .ok_or(e) - }) - .context("Trying to read env var `WASMER_DIR`")?, - )) -} - -fn get_wasmer_include_directory() -> anyhow::Result { - let mut path = get_wasmer_dir()?; - path.push("include"); - Ok(path) -} - -/// path to the static libwasmer -fn get_libwasmer_path() -> anyhow::Result { - let mut path = get_wasmer_dir()?; - path.push("lib"); - - // TODO: prefer headless Wasmer if/when it's a separate library. - #[cfg(not(windows))] - path.push("libwasmer.a"); - #[cfg(windows)] - path.push("wasmer.lib"); - - Ok(path) -} - -/// Compile the C code. -fn run_c_compile( - path_to_c_src: &Path, - output_name: &Path, - target: Option, -) -> anyhow::Result<()> { - #[cfg(not(windows))] - let c_compiler = "cc"; - // We must use a C++ compiler on Windows because wasm.h uses `static_assert` - // which isn't available in `clang` on Windows. - #[cfg(windows)] - let c_compiler = "clang++"; - - let mut command = Command::new(c_compiler); - let command = command - .arg("-O2") - .arg("-c") - .arg(path_to_c_src) - .arg("-I") - .arg(get_wasmer_include_directory()?); - - let command = if let Some(target) = target { - command.arg("-target").arg(format!("{}", target)) - } else { - command - }; - - let output = command.arg("-o").arg(output_name).output()?; - - if !output.status.success() { - bail!( - "C code compile failed with: stdout: {}\n\nstderr: {}", - std::str::from_utf8(&output.stdout) - .expect("stdout is not utf8! need to handle arbitrary bytes"), - std::str::from_utf8(&output.stderr) - .expect("stderr is not utf8! need to handle arbitrary bytes") - ); - } - Ok(()) -} - -/// Data used to run a linking command for generated artifacts. -#[derive(Debug)] -struct LinkCode { - /// Path to the linker used to run the linking command. - linker_path: PathBuf, - /// String used as an optimization flag. - optimization_flag: String, - /// Paths of objects to link. - object_paths: Vec, - /// Additional libraries to link against. - additional_libraries: Vec, - /// Path to the output target. - output_path: PathBuf, - /// Path to the dir containing the static libwasmer library. - libwasmer_path: PathBuf, - /// The target to link the executable for. - target: Option, -} - -impl Default for LinkCode { - fn default() -> Self { - #[cfg(not(windows))] - let linker = "cc"; - #[cfg(windows)] - let linker = "clang"; - Self { - linker_path: PathBuf::from(linker), - optimization_flag: String::from("-O2"), - object_paths: vec![], - additional_libraries: vec![], - output_path: PathBuf::from("a.out"), - libwasmer_path: get_libwasmer_path().unwrap(), - target: None, - } - } -} - -impl LinkCode { - fn run(&self) -> anyhow::Result<()> { - let mut command = Command::new(&self.linker_path); - let command = command - .arg(&self.optimization_flag) - .args( - self.object_paths - .iter() - .map(|path| path.canonicalize().unwrap()), - ) - .arg( - &self - .libwasmer_path - .canonicalize() - .context("Failed to find libwasmer")?, - ); - let command = if let Some(target) = &self.target { - command.arg("-target").arg(format!("{}", target)) - } else { - command - }; - // Add libraries required per platform. - // We need userenv, sockets (Ws2_32), advapi32 for some system calls and bcrypt for random numbers. - #[cfg(windows)] - let command = command - .arg("-luserenv") - .arg("-lWs2_32") - .arg("-ladvapi32") - .arg("-lbcrypt"); - // On unix we need dlopen-related symbols, libmath for a few things, and pthreads. - #[cfg(not(windows))] - let command = command.arg("-ldl").arg("-lm").arg("-pthread"); - let link_aganist_extra_libs = self - .additional_libraries - .iter() - .map(|lib| format!("-l{}", lib)); - let command = command.args(link_aganist_extra_libs); - let output = command.arg("-o").arg(&self.output_path).output()?; - - if !output.status.success() { - bail!( - "linking failed with: stdout: {}\n\nstderr: {}", - std::str::from_utf8(&output.stdout) - .expect("stdout is not utf8! need to handle arbitrary bytes"), - std::str::from_utf8(&output.stderr) - .expect("stderr is not utf8! need to handle arbitrary bytes") - ); - } - Ok(()) - } -} diff --git a/lib/cli/src/commands/inspect.rs b/lib/cli/src/commands/inspect.rs index 4858c749ac8..e1a99e618bd 100644 --- a/lib/cli/src/commands/inspect.rs +++ b/lib/cli/src/commands/inspect.rs @@ -23,7 +23,7 @@ impl Inspect { .context(format!("failed to inspect `{}`", self.path.display())) } fn inner_execute(&self) -> Result<()> { - let (store, _engine_type, _compiler_type) = self.store.get_store()?; + let (store, _compiler_type) = self.store.get_store()?; let module_contents = std::fs::read(&self.path)?; let module = Module::new(&store, &module_contents)?; println!( diff --git a/lib/cli/src/commands/run.rs b/lib/cli/src/commands/run.rs index e2f799751bd..ec7b81a2cfc 100644 --- a/lib/cli/src/commands/run.rs +++ b/lib/cli/src/commands/run.rs @@ -1,7 +1,7 @@ use crate::common::get_cache_dir; #[cfg(feature = "debug")] use crate::logging; -use crate::store::{CompilerType, EngineType, StoreOptions}; +use crate::store::{CompilerType, StoreOptions}; use crate::suggestions::suggest_function_exports; use crate::warning; use anyhow::{anyhow, Context, Result}; @@ -223,28 +223,16 @@ impl Run { fn get_module(&self) -> Result { let contents = std::fs::read(self.path.clone())?; - #[cfg(feature = "dylib")] - { - if wasmer_engine_dylib::DylibArtifact::is_deserializable(&contents) { - let engine = wasmer_engine_dylib::Dylib::headless().engine(); - let store = Store::new(&engine); - let module = unsafe { Module::deserialize_from_file(&store, &self.path)? }; - return Ok(module); - } - } - #[cfg(feature = "universal")] - { - if wasmer_engine_universal::UniversalArtifact::is_deserializable(&contents) { - let engine = wasmer_engine_universal::Universal::headless().engine(); - let store = Store::new(&engine); - let module = unsafe { Module::deserialize_from_file(&store, &self.path)? }; - return Ok(module); - } + if wasmer_compiler::UniversalArtifact::is_deserializable(&contents) { + let engine = wasmer_compiler::Universal::headless().engine(); + let store = Store::new_with_engine(&engine); + let module = unsafe { Module::deserialize_from_file(&store, &self.path)? }; + return Ok(module); } - let (store, engine_type, compiler_type) = self.store.get_store()?; + let (store, compiler_type) = self.store.get_store()?; #[cfg(feature = "cache")] let module_result: Result = if !self.disable_cache && contents.len() > 0x1000 { - self.get_module_from_cache(&store, &contents, &engine_type, &compiler_type) + self.get_module_from_cache(&store, &contents, &compiler_type) } else { Module::new(&store, &contents).map_err(|e| e.into()) }; @@ -253,8 +241,7 @@ impl Run { let mut module = module_result.with_context(|| { format!( - "module instantiation failed (engine: {}, compiler: {})", - engine_type.to_string(), + "module instantiation failed (compiler: {})", compiler_type.to_string() ) })?; @@ -269,14 +256,13 @@ impl Run { &self, store: &Store, contents: &[u8], - engine_type: &EngineType, compiler_type: &CompilerType, ) -> Result { // We try to get it from cache, in case caching is enabled // and the file length is greater than 4KB. // For files smaller than 4KB caching is not worth, // as it takes space and the speedup is minimal. - let mut cache = self.get_cache(engine_type, compiler_type)?; + let mut cache = self.get_cache(compiler_type)?; // Try to get the hash from the provided `--cache-key`, otherwise // generate one from the provided file `.wasm` contents. let hash = self @@ -305,33 +291,13 @@ impl Run { #[cfg(feature = "cache")] /// Get the Compiler Filesystem cache - fn get_cache( - &self, - engine_type: &EngineType, - compiler_type: &CompilerType, - ) -> Result { + fn get_cache(&self, compiler_type: &CompilerType) -> Result { let mut cache_dir_root = get_cache_dir(); cache_dir_root.push(compiler_type.to_string()); let mut cache = FileSystemCache::new(cache_dir_root)?; - // Important: Dylib files need to have a `.dll` extension on - // Windows, otherwise they will not load, so we just add an - // extension always to make it easier to recognize as well. - #[allow(unreachable_patterns)] - let extension = match *engine_type { - #[cfg(feature = "dylib")] - EngineType::Dylib => { - wasmer_engine_dylib::DylibArtifact::get_default_extension(&Triple::host()) - .to_string() - } - #[cfg(feature = "universal")] - EngineType::Universal => { - wasmer_engine_universal::UniversalArtifact::get_default_extension(&Triple::host()) - .to_string() - } - // We use the compiler type as the default extension - _ => compiler_type.to_string(), - }; + let extension = + wasmer_compiler::UniversalArtifact::get_default_extension(&Triple::host()).to_string(); cache.set_cache_extension(Some(extension)); Ok(cache) } diff --git a/lib/cli/src/commands/validate.rs b/lib/cli/src/commands/validate.rs index fb9554d684e..f429c8ab6b5 100644 --- a/lib/cli/src/commands/validate.rs +++ b/lib/cli/src/commands/validate.rs @@ -22,7 +22,7 @@ impl Validate { .context(format!("failed to validate `{}`", self.path.display())) } fn inner_execute(&self) -> Result<()> { - let (store, _engine_type, _compiler_type) = self.store.get_store()?; + let (store, _compiler_type) = self.store.get_store()?; let module_contents = std::fs::read(&self.path)?; if !is_wasm(&module_contents) { bail!("`wasmer validate` only validates WebAssembly files"); diff --git a/lib/cli/src/commands/wasmer_create_exe_main.c b/lib/cli/src/commands/wasmer_create_exe_main.c deleted file mode 100644 index 3661ffa9d29..00000000000 --- a/lib/cli/src/commands/wasmer_create_exe_main.c +++ /dev/null @@ -1,171 +0,0 @@ -#include "wasmer.h" -#include "my_wasm.h" - -#include -#include -#include - -#define own - -// TODO: make this define templated so that the Rust code can toggle it on/off -#define WASI - -static void print_wasmer_error() { - int error_len = wasmer_last_error_length(); - if (error_len > 0) { - printf("Error len: `%d`\n", error_len); - char *error_str = (char *)malloc(error_len); - wasmer_last_error_message(error_str, error_len); - printf("%s\n", error_str); - free(error_str); - } -} - -#ifdef WASI -static void pass_mapdir_arg(wasi_config_t *wasi_config, char *mapdir) { - int colon_location = strchr(mapdir, ':') - mapdir; - if (colon_location == 0) { - // error malformed argument - fprintf(stderr, "Expected mapdir argument of the form alias:directory\n"); - exit(-1); - } - - char *alias = (char *)malloc(colon_location + 1); - memcpy(alias, mapdir, colon_location); - alias[colon_location] = '\0'; - - int dir_len = strlen(mapdir) - colon_location; - char *dir = (char *)malloc(dir_len + 1); - memcpy(dir, &mapdir[colon_location + 1], dir_len); - dir[dir_len] = '\0'; - - wasi_config_mapdir(wasi_config, alias, dir); - free(alias); - free(dir); -} - -// We try to parse out `--dir` and `--mapdir` ahead of time and process those -// specially. All other arguments are passed to the guest program. -static void handle_arguments(wasi_config_t *wasi_config, int argc, - char *argv[]) { - for (int i = 1; i < argc; ++i) { - // We probably want special args like `--dir` and `--mapdir` to not be - // passed directly - if (strcmp(argv[i], "--dir") == 0) { - // next arg is a preopen directory - if ((i + 1) < argc) { - i++; - wasi_config_preopen_dir(wasi_config, argv[i]); - } else { - fprintf(stderr, "--dir expects a following argument specifying which " - "directory to preopen\n"); - exit(-1); - } - } else if (strcmp(argv[i], "--mapdir") == 0) { - // next arg is a mapdir - if ((i + 1) < argc) { - i++; - pass_mapdir_arg(wasi_config, argv[i]); - } else { - fprintf(stderr, - "--mapdir expects a following argument specifying which " - "directory to preopen in the form alias:directory\n"); - exit(-1); - } - } else if (strncmp(argv[i], "--dir=", strlen("--dir=")) == 0) { - // this arg is a preopen dir - char *dir = argv[i] + strlen("--dir="); - wasi_config_preopen_dir(wasi_config, dir); - } else if (strncmp(argv[i], "--mapdir=", strlen("--mapdir=")) == 0) { - // this arg is a mapdir - char *mapdir = argv[i] + strlen("--mapdir="); - pass_mapdir_arg(wasi_config, mapdir); - } else { - // guest argument - wasi_config_arg(wasi_config, argv[i]); - } - } -} -#endif - -int main(int argc, char *argv[]) { - wasm_config_t *config = wasm_config_new(); - wasm_config_set_engine(config, STATICLIB); - wasm_engine_t *engine = wasm_engine_new_with_config(config); - wasm_store_t *store = wasm_store_new(engine); - - wasm_module_t *module = wasmer_staticlib_engine_new(store, argv[0]); - - if (!module) { - fprintf(stderr, "Failed to create module\n"); - print_wasmer_error(); - return -1; - } - - // We have now finished the memory buffer book keeping and we have a valid - // Module. - -#ifdef WASI - wasi_config_t *wasi_config = wasi_config_new(argv[0]); - handle_arguments(wasi_config, argc, argv); - - wasi_env_t *wasi_env = wasi_env_new(wasi_config); - if (!wasi_env) { - fprintf(stderr, "Error building WASI env!\n"); - print_wasmer_error(); - return 1; - } -#endif - - wasm_importtype_vec_t import_types; - wasm_module_imports(module, &import_types); - - wasm_extern_vec_t imports; - wasm_extern_vec_new_uninitialized(&imports, import_types.size); - wasm_importtype_vec_delete(&import_types); - -#ifdef WASI - bool get_imports_result = wasi_get_imports(store, module, wasi_env, &imports); - wasi_env_delete(wasi_env); - - if (!get_imports_result) { - fprintf(stderr, "Error getting WASI imports!\n"); - print_wasmer_error(); - - return 1; - } -#endif - - wasm_instance_t *instance = wasm_instance_new(store, module, &imports, NULL); - - if (!instance) { - fprintf(stderr, "Failed to create instance\n"); - print_wasmer_error(); - return -1; - } - -#ifdef WASI - own wasm_func_t *start_function = wasi_get_start_function(instance); - if (!start_function) { - fprintf(stderr, "`_start` function not found\n"); - print_wasmer_error(); - return -1; - } - - wasm_val_vec_t args = WASM_EMPTY_VEC; - wasm_val_vec_t results = WASM_EMPTY_VEC; - own wasm_trap_t *trap = wasm_func_call(start_function, &args, &results); - if (trap) { - fprintf(stderr, "Trap is not NULL: TODO:\n"); - return -1; - } -#endif - - // TODO: handle non-WASI start (maybe with invoke?) - - wasm_instance_delete(instance); - wasm_module_delete(module); - wasm_store_delete(store); - wasm_engine_delete(engine); - return 0; -} diff --git a/lib/cli/src/commands/wast.rs b/lib/cli/src/commands/wast.rs index 2837069f21f..580bdb205e1 100644 --- a/lib/cli/src/commands/wast.rs +++ b/lib/cli/src/commands/wast.rs @@ -27,7 +27,7 @@ impl Wast { .context(format!("failed to test the wast `{}`", self.path.display())) } fn inner_execute(&self) -> Result<()> { - let (store, _engine_name, _compiler_name) = self.store.get_store()?; + let (store, _compiler_name) = self.store.get_store()?; let mut wast = WastSpectest::new_with_spectest(store); wast.fail_fast = self.fail_fast; wast.run_file(&self.path).with_context(|| "tests failed")?; diff --git a/lib/cli/src/lib.rs b/lib/cli/src/lib.rs index 7a80b9fae69..4cb32b02bee 100644 --- a/lib/cli/src/lib.rs +++ b/lib/cli/src/lib.rs @@ -20,7 +20,6 @@ pub mod commands; pub mod common; #[macro_use] pub mod error; -pub mod c_gen; pub mod cli; #[cfg(feature = "debug")] pub mod logging; diff --git a/lib/cli/src/store.rs b/lib/cli/src/store.rs index a2044c1925c..f5893d64523 100644 --- a/lib/cli/src/store.rs +++ b/lib/cli/src/store.rs @@ -16,35 +16,11 @@ use wasmer::*; use wasmer_compiler::CompilerConfig; #[derive(Debug, Clone, StructOpt, Default)] -/// The compiler and engine options +/// The compiler options pub struct StoreOptions { #[cfg(feature = "compiler")] #[structopt(flatten)] compiler: CompilerOptions, - - /// Use the Universal Engine. - #[structopt(long, conflicts_with_all = &["dylib", "staticlib", "jit", "native", "object_file"])] - universal: bool, - - /// Use the Dylib Engine. - #[structopt(long, conflicts_with_all = &["universal", "staticlib", "jit", "native", "object_file"])] - dylib: bool, - - /// Use the Staticlib Engine. - #[structopt(long, conflicts_with_all = &["universal", "dylib", "jit", "native", "object_file"])] - staticlib: bool, - - /// Use the JIT (Universal) Engine. - #[structopt(long, hidden = true, conflicts_with_all = &["universal", "dylib", "staticlib", "native", "object_file"])] - jit: bool, - - /// Use the Native (Dylib) Engine. - #[structopt(long, hidden = true, conflicts_with_all = &["universal", "dylib", "staticlib", "jit", "object_file"])] - native: bool, - - /// Use the ObjectFile (Staticlib) Engine. - #[structopt(long, hidden = true, conflicts_with_all = &["universal", "dylib", "staticlib", "jit", "native"])] - object_file: bool, } #[cfg(feature = "compiler")] @@ -65,6 +41,7 @@ pub struct CompilerOptions { /// Enable compiler internal verification. #[structopt(long)] + #[cfg(any(feature = "singlepass", feature = "cranelift", feature = "llvm"))] enable_verifier: bool, /// LLVM debug directory, where IR and object files will be written to. @@ -123,53 +100,26 @@ impl CompilerOptions { Ok(features) } - /// Gets the Store for a given target and engine. - pub fn get_store_for_target_and_engine( - &self, - target: Target, - engine_type: EngineType, - ) -> Result<(Store, CompilerType)> { + /// Gets the Store for a given target. + pub fn get_store_for_target(&self, target: Target) -> Result<(Store, CompilerType)> { let (compiler_config, compiler_type) = self.get_compiler_config()?; - let engine = self.get_engine_by_type(target, compiler_config, engine_type)?; - let store = Store::new(&*engine); + let engine = self.get_engine(target, compiler_config)?; + let store = Store::new_with_engine(&*engine); Ok((store, compiler_type)) } - fn get_engine_by_type( + fn get_engine( &self, target: Target, compiler_config: Box, - engine_type: EngineType, ) -> Result> { let features = self.get_features(compiler_config.default_features_for_target(&target))?; - let engine: Box = match engine_type { - #[cfg(feature = "universal")] - EngineType::Universal => Box::new( - wasmer_engine_universal::Universal::new(compiler_config) - .features(features) - .target(target) - .engine(), - ), - #[cfg(feature = "dylib")] - EngineType::Dylib => Box::new( - wasmer_engine_dylib::Dylib::new(compiler_config) - .target(target) - .features(features) - .engine(), - ), - #[cfg(feature = "staticlib")] - EngineType::Staticlib => Box::new( - wasmer_engine_staticlib::Staticlib::new(compiler_config) - .target(target) - .features(features) - .engine(), - ), - #[cfg(not(all(feature = "universal", feature = "dylib", feature = "staticlib")))] - engine => bail!( - "The `{}` engine is not included in this binary.", - engine.to_string() - ), - }; + let engine: Box = Box::new( + wasmer_compiler::Universal::new(compiler_config) + .features(features) + .target(target) + .engine(), + ); Ok(engine) } @@ -351,138 +301,46 @@ impl ToString for CompilerType { } } -/// The engine used for the store -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum EngineType { - /// Universal Engine - Universal, - /// Dylib Engine - Dylib, - /// Static Engine - Staticlib, -} - -impl ToString for EngineType { - fn to_string(&self) -> String { - match self { - Self::Universal => "universal".to_string(), - Self::Dylib => "dylib".to_string(), - Self::Staticlib => "staticlib".to_string(), - } - } -} - -#[cfg(all(feature = "compiler", feature = "engine"))] +#[cfg(all(feature = "compiler"))] impl StoreOptions { - /// Gets the store for the host target, with the engine name and compiler name selected - pub fn get_store(&self) -> Result<(Store, EngineType, CompilerType)> { + /// Gets the store for the host target, with the compiler name selected + pub fn get_store(&self) -> Result<(Store, CompilerType)> { let target = Target::default(); self.get_store_for_target(target) } - /// Gets the store for a given target, with the engine name and compiler name selected, as - pub fn get_store_for_target( - &self, - target: Target, - ) -> Result<(Store, EngineType, CompilerType)> { + /// Gets the store for a given target, with the compiler name selected. + pub fn get_store_for_target(&self, target: Target) -> Result<(Store, CompilerType)> { let (compiler_config, compiler_type) = self.compiler.get_compiler_config()?; - let (engine, engine_type) = self.get_engine_with_compiler(target, compiler_config)?; - let store = Store::new(&*engine); - Ok((store, engine_type, compiler_type)) + let engine = self.get_engine_with_compiler(target, compiler_config)?; + let store = Store::new_with_engine(&*engine); + Ok((store, compiler_type)) } fn get_engine_with_compiler( &self, target: Target, compiler_config: Box, - ) -> Result<(Box, EngineType)> { - let engine_type = self.get_engine()?; - let engine = self - .compiler - .get_engine_by_type(target, compiler_config, engine_type)?; - - Ok((engine, engine_type)) - } -} + ) -> Result> { + let engine = self.compiler.get_engine(target, compiler_config)?; -#[cfg(feature = "engine")] -impl StoreOptions { - fn get_engine(&self) -> Result { - if self.universal || self.jit { - Ok(EngineType::Universal) - } else if self.dylib || self.native { - Ok(EngineType::Dylib) - } else if self.staticlib || self.object_file { - Ok(EngineType::Staticlib) - } else { - // Auto mode, we choose the best engine for that platform - if cfg!(feature = "universal") { - Ok(EngineType::Universal) - } else if cfg!(feature = "dylib") { - Ok(EngineType::Dylib) - } else if cfg!(feature = "staticlib") { - Ok(EngineType::Staticlib) - } else { - bail!("There are no available engines for your architecture") - } - } + Ok(engine) } } // If we don't have a compiler, but we have an engine -#[cfg(all(not(feature = "compiler"), feature = "engine"))] +#[cfg(not(feature = "compiler"))] impl StoreOptions { - fn get_engine_headless(&self) -> Result<(Arc, EngineType)> { - let engine_type = self.get_engine()?; - let engine: Arc = match engine_type { - #[cfg(feature = "universal")] - EngineType::Universal => { - Arc::new(wasmer_engine_universal::Universal::headless().engine()) - } - #[cfg(feature = "dylib")] - EngineType::Dylib => Arc::new(wasmer_engine_dylib::Dylib::headless().engine()), - #[cfg(feature = "staticlib")] - EngineType::Staticlib => { - Arc::new(wasmer_engine_staticlib::Staticlib::headless().engine()) - } - #[cfg(not(all(feature = "universal", feature = "dylib", feature = "staticlib")))] - engine => bail!( - "The `{}` engine is not included in this binary.", - engine.to_string() - ), - }; - Ok((engine, engine_type)) - } - - /// Get the store (headless engine) - pub fn get_store(&self) -> Result<(Store, EngineType, CompilerType)> { - let (engine, engine_type) = self.get_engine_headless()?; - let store = Store::new(&*engine); - Ok((store, engine_type, CompilerType::Headless)) + fn get_engine_headless(&self) -> Result> { + let engine: Arc = + Arc::new(wasmer_compiler::Universal::headless().engine()); + Ok(engine) } - /// Gets the store for provided host target - pub fn get_store_for_target( - &self, - _target: Target, - ) -> Result<(Store, EngineType, CompilerType)> { - bail!("You need compilers to retrieve a store for a specific target"); - } -} - -// If we don't have any engine enabled -#[cfg(not(feature = "engine"))] -impl StoreOptions { /// Get the store (headless engine) - pub fn get_store(&self) -> Result<(Store, EngineType, CompilerType)> { - bail!("No engines are enabled"); - } - - /// Gets the store for the host target - pub fn get_store_for_target( - &self, - _target: Target, - ) -> Result<(Store, EngineType, CompilerType)> { - bail!("No engines are enabled"); + pub fn get_store(&self) -> Result<(Store, CompilerType)> { + let engine = self.get_engine_headless()?; + let store = Store::new_with_engine(&*engine); + Ok((store, CompilerType::Headless)) } } diff --git a/lib/compiler-cranelift/README.md b/lib/compiler-cranelift/README.md index f10abbe30ba..716e9ddea47 100644 --- a/lib/compiler-cranelift/README.md +++ b/lib/compiler-cranelift/README.md @@ -10,7 +10,7 @@ use wasmer_compiler_cranelift::Cranelift; let compiler = Cranelift::new(); // Put it into an engine and add it to the store -let store = Store::new(&Universal::new(compiler).engine()); +let store = Store::new_with_engine(&Universal::new(compiler).engine()); ``` *Note: you can find a [full working example using Cranelift compiler diff --git a/lib/compiler-cranelift/src/address_map.rs b/lib/compiler-cranelift/src/address_map.rs index 5296c108215..3f6e22c54a5 100644 --- a/lib/compiler-cranelift/src/address_map.rs +++ b/lib/compiler-cranelift/src/address_map.rs @@ -3,7 +3,8 @@ use cranelift_codegen::Context; use cranelift_codegen::MachSrcLoc; -use wasmer_compiler::{wasmparser::Range, FunctionAddressMap, InstructionAddressMap, SourceLoc}; +use wasmer_compiler::wasmparser::Range; +use wasmer_types::{FunctionAddressMap, InstructionAddressMap, SourceLoc}; pub fn get_function_address_map( context: &Context, diff --git a/lib/compiler-cranelift/src/compiler.rs b/lib/compiler-cranelift/src/compiler.rs index eeafb306f66..bff5b42122e 100644 --- a/lib/compiler-cranelift/src/compiler.rs +++ b/lib/compiler-cranelift/src/compiler.rs @@ -21,19 +21,18 @@ use gimli::write::{Address, EhFrame, FrameTable}; #[cfg(feature = "rayon")] use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; use std::sync::Arc; +use wasmer_compiler::{CallingConvention, ModuleTranslationState, Target}; use wasmer_compiler::{ - CallingConvention, ModuleTranslationState, RelocationTarget, Target, TrapInformation, + Compiler, FunctionBinaryReader, FunctionBodyData, MiddlewareBinaryReader, ModuleMiddleware, + ModuleMiddlewareChain, }; -use wasmer_compiler::{ +use wasmer_types::entity::{EntityRef, PrimaryMap}; +use wasmer_types::{ Compilation, CompileModuleInfo, CompiledFunction, CompiledFunctionFrameInfo, - CompiledFunctionUnwindInfo, Compiler, Dwarf, FunctionBinaryReader, FunctionBody, - FunctionBodyData, MiddlewareBinaryReader, ModuleMiddleware, ModuleMiddlewareChain, - SectionIndex, + CompiledFunctionUnwindInfo, Dwarf, FunctionBody, TrapInformation, }; -use wasmer_compiler::{CompileError, Relocation}; -use wasmer_types::entity::{EntityRef, PrimaryMap}; -use wasmer_types::TrapCode; -use wasmer_types::{FunctionIndex, LocalFunctionIndex, ModuleInfo, SignatureIndex}; +use wasmer_types::{CompileError, FunctionIndex, LocalFunctionIndex, ModuleInfo, SignatureIndex}; +use wasmer_types::{Relocation, RelocationTarget, SectionIndex, TrapCode}; /// A compiler that compiles a WebAssembly module with Cranelift, translating the Wasm to Cranelift IR, /// optimizing it and then translating to assembly. diff --git a/lib/compiler-cranelift/src/config.rs b/lib/compiler-cranelift/src/config.rs index 84f4ff30f2e..6b7c02ab1b4 100644 --- a/lib/compiler-cranelift/src/config.rs +++ b/lib/compiler-cranelift/src/config.rs @@ -135,7 +135,7 @@ impl Cranelift { flags.enable("is_pic").expect("should be a valid flag"); } - // We set up libcall trampolines in engine-dylib and engine-universal. + // We set up libcall trampolines in engine-universal. // These trampolines are always reachable through short jumps. flags .enable("use_colocated_libcalls") diff --git a/lib/compiler-cranelift/src/dwarf.rs b/lib/compiler-cranelift/src/dwarf.rs index d079c288587..dab284c9d9e 100644 --- a/lib/compiler-cranelift/src/dwarf.rs +++ b/lib/compiler-cranelift/src/dwarf.rs @@ -1,9 +1,12 @@ use gimli::write::{Address, EndianVec, Result, Writer}; use gimli::{RunTimeEndian, SectionId}; -use wasmer_compiler::{CustomSection, CustomSectionProtection, SectionBody}; -use wasmer_compiler::{Endianness, Relocation, RelocationKind, RelocationTarget}; +use wasmer_compiler::Endianness; use wasmer_types::entity::EntityRef; use wasmer_types::LocalFunctionIndex; +use wasmer_types::{ + CustomSection, CustomSectionProtection, Relocation, RelocationKind, RelocationTarget, + SectionBody, +}; #[derive(Clone, Debug)] pub struct WriterRelocate { @@ -78,7 +81,7 @@ impl Writer for WriterRelocate { offset, addend, }); - self.write_udata(addend as u64, size) + self.write_udata(addend as _, size) } else { unreachable!("Symbol {} in DWARF not recognized", symbol); } diff --git a/lib/compiler-cranelift/src/func_environ.rs b/lib/compiler-cranelift/src/func_environ.rs index ed9377f9569..96c627d9a80 100644 --- a/lib/compiler-cranelift/src/func_environ.rs +++ b/lib/compiler-cranelift/src/func_environ.rs @@ -14,7 +14,6 @@ use cranelift_codegen::isa::TargetFrontendConfig; use cranelift_frontend::{FunctionBuilder, Variable}; use std::convert::TryFrom; use wasmer_compiler::wasmparser::Type; -use wasmer_compiler::{WasmError, WasmResult}; use wasmer_types::entity::EntityRef; use wasmer_types::entity::PrimaryMap; use wasmer_types::VMBuiltinFunctionIndex; @@ -24,6 +23,7 @@ use wasmer_types::{ SignatureIndex, TableIndex, Type as WasmerType, }; use wasmer_types::{MemoryStyle, TableStyle}; +use wasmer_types::{WasmError, WasmResult}; /// Compute an `ir::ExternalName` for a given wasm function index. pub fn get_function_name(func_index: FunctionIndex) -> ir::ExternalName { diff --git a/lib/compiler-cranelift/src/trampoline/dynamic_function.rs b/lib/compiler-cranelift/src/trampoline/dynamic_function.rs index 9ebaad8942f..37ea9d46fa0 100644 --- a/lib/compiler-cranelift/src/trampoline/dynamic_function.rs +++ b/lib/compiler-cranelift/src/trampoline/dynamic_function.rs @@ -15,9 +15,7 @@ use std::cmp; use std::mem; use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; -use wasmer_compiler::{CompileError, FunctionBody}; -use wasmer_types::FunctionType; -use wasmer_types::VMOffsets; +use wasmer_types::{CompileError, FunctionBody, FunctionType, VMOffsets}; /// Create a trampoline for invoking a WebAssembly function. pub fn make_trampoline_dynamic_function( diff --git a/lib/compiler-cranelift/src/trampoline/function_call.rs b/lib/compiler-cranelift/src/trampoline/function_call.rs index 2c519c7d44c..12d8d2eb7d8 100644 --- a/lib/compiler-cranelift/src/trampoline/function_call.rs +++ b/lib/compiler-cranelift/src/trampoline/function_call.rs @@ -16,8 +16,7 @@ use cranelift_codegen::print_errors::pretty_error; use cranelift_codegen::Context; use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use std::mem; -use wasmer_compiler::{CompileError, FunctionBody}; -use wasmer_types::FunctionType; +use wasmer_types::{CompileError, FunctionBody, FunctionType}; /// Create a trampoline for invoking a WebAssembly function. pub fn make_trampoline_function_call( diff --git a/lib/compiler-cranelift/src/translator/code_translator.rs b/lib/compiler-cranelift/src/translator/code_translator.rs index 490eed9c560..99d1a57ba55 100644 --- a/lib/compiler-cranelift/src/translator/code_translator.rs +++ b/lib/compiler-cranelift/src/translator/code_translator.rs @@ -93,10 +93,10 @@ use smallvec::SmallVec; use std::vec::Vec; use wasmer_compiler::wasmparser::{MemoryImmediate, Operator, Type as WPType}; -use wasmer_compiler::WasmResult; -use wasmer_compiler::{wasm_unsupported, ModuleTranslationState}; +use wasmer_compiler::{from_binaryreadererror_wasmerror, wasm_unsupported, ModuleTranslationState}; use wasmer_types::{ FunctionIndex, GlobalIndex, MemoryIndex, SignatureIndex, TableIndex, Type as WasmerType, + WasmResult, }; // Clippy warns about "align: _" but its important to document that the align field is ignored @@ -486,7 +486,7 @@ pub fn translate_operator( let default = table.default(); let mut min_depth = default; for depth in table.targets() { - let depth = depth?; + let depth = depth.map_err(from_binaryreadererror_wasmerror)?; if depth < min_depth { min_depth = depth; } @@ -505,7 +505,7 @@ pub fn translate_operator( if jump_args_count == 0 { // No jump arguments for depth in table.targets() { - let depth = depth?; + let depth = depth.map_err(from_binaryreadererror_wasmerror)?; let block = { let i = state.control_stack.len() - 1 - (depth as usize); let frame = &mut state.control_stack[i]; @@ -529,7 +529,7 @@ pub fn translate_operator( let mut dest_block_sequence = vec![]; let mut dest_block_map = HashMap::new(); for depth in table.targets() { - let depth = depth?; + let depth = depth.map_err(from_binaryreadererror_wasmerror)?; let branch_block = match dest_block_map.entry(depth as usize) { hash_map::Entry::Occupied(entry) => *entry.get(), hash_map::Entry::Vacant(entry) => { diff --git a/lib/compiler-cranelift/src/translator/func_environ.rs b/lib/compiler-cranelift/src/translator/func_environ.rs index b5f5b176a59..f5a38674210 100644 --- a/lib/compiler-cranelift/src/translator/func_environ.rs +++ b/lib/compiler-cranelift/src/translator/func_environ.rs @@ -13,10 +13,9 @@ use cranelift_codegen::ir::{self, InstBuilder}; use cranelift_codegen::isa::TargetFrontendConfig; use cranelift_frontend::FunctionBuilder; use wasmer_compiler::wasmparser::{Operator, Type}; -use wasmer_compiler::WasmResult; use wasmer_types::{ FunctionIndex, FunctionType, GlobalIndex, LocalFunctionIndex, MemoryIndex, SignatureIndex, - TableIndex, Type as WasmerType, + TableIndex, Type as WasmerType, WasmResult, }; /// The value of a WebAssembly global variable. diff --git a/lib/compiler-cranelift/src/translator/func_state.rs b/lib/compiler-cranelift/src/translator/func_state.rs index 6255b9e3274..30da9e7c0c4 100644 --- a/lib/compiler-cranelift/src/translator/func_state.rs +++ b/lib/compiler-cranelift/src/translator/func_state.rs @@ -13,8 +13,9 @@ use super::func_environ::{FuncEnvironment, GlobalVariable}; use crate::{HashMap, Occupied, Vacant}; use cranelift_codegen::ir::{self, Block, Inst, Value}; use std::vec::Vec; -use wasmer_compiler::WasmResult; -use wasmer_types::{FunctionIndex, GlobalIndex, MemoryIndex, SignatureIndex, TableIndex}; +use wasmer_types::{ + FunctionIndex, GlobalIndex, MemoryIndex, SignatureIndex, TableIndex, WasmResult, +}; /// Information about the presence of an associated `else` for an `if`, or the /// lack thereof. diff --git a/lib/compiler-cranelift/src/translator/func_translator.rs b/lib/compiler-cranelift/src/translator/func_translator.rs index 8e2cb145d22..13bc07da532 100644 --- a/lib/compiler-cranelift/src/translator/func_translator.rs +++ b/lib/compiler-cranelift/src/translator/func_translator.rs @@ -18,9 +18,9 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable}; use tracing::info; use wasmer_compiler::wasmparser; use wasmer_compiler::{ - wasm_unsupported, wptype_to_type, FunctionBinaryReader, ModuleTranslationState, WasmResult, + wasm_unsupported, wptype_to_type, FunctionBinaryReader, ModuleTranslationState, }; -use wasmer_types::LocalFunctionIndex; +use wasmer_types::{LocalFunctionIndex, WasmResult}; /// WebAssembly to Cranelift IR function translator. /// diff --git a/lib/compiler-cranelift/src/translator/translation_utils.rs b/lib/compiler-cranelift/src/translator/translation_utils.rs index a0277c8b866..db0cc50e49f 100644 --- a/lib/compiler-cranelift/src/translator/translation_utils.rs +++ b/lib/compiler-cranelift/src/translator/translation_utils.rs @@ -9,9 +9,7 @@ use cranelift_codegen::isa::TargetFrontendConfig; use cranelift_frontend::FunctionBuilder; use wasmer_compiler::wasm_unsupported; use wasmer_compiler::wasmparser; -use wasmer_compiler::RelocationKind; -use wasmer_compiler::{WasmError, WasmResult}; -use wasmer_types::{FunctionType, LibCall, Type}; +use wasmer_types::{FunctionType, LibCall, RelocationKind, Type, WasmError, WasmResult}; /// Helper function translate a Function signature into Cranelift Ir pub fn signature_to_cranelift_ir( diff --git a/lib/compiler-cranelift/src/translator/unwind.rs b/lib/compiler-cranelift/src/translator/unwind.rs index 574a6ff8240..1aff474ddce 100644 --- a/lib/compiler-cranelift/src/translator/unwind.rs +++ b/lib/compiler-cranelift/src/translator/unwind.rs @@ -5,7 +5,8 @@ use cranelift_codegen::isa::unwind::{systemv::UnwindInfo as DwarfFDE, UnwindInfo}; use cranelift_codegen::print_errors::pretty_error; use cranelift_codegen::{isa, Context}; -use wasmer_compiler::{CompileError, CompiledFunctionUnwindInfo}; +use wasmer_types::CompileError; +use wasmer_types::CompiledFunctionUnwindInfo; /// Cranelift specific unwind info pub(crate) enum CraneliftUnwindInfo { diff --git a/lib/compiler-llvm/README.md b/lib/compiler-llvm/README.md index 51368ebe237..782784b0b11 100644 --- a/lib/compiler-llvm/README.md +++ b/lib/compiler-llvm/README.md @@ -10,7 +10,7 @@ use wasmer_compiler_llvm::LLVM; let compiler = LLVM::new(); // Put it into an engine and add it to the store -let store = Store::new(&Universal::new(compiler).engine()); +let store = Store::new_with_engine(&Universal::new(compiler).engine()); ``` *Note: you can find a [full working example using LLVM compiler here][example].* diff --git a/lib/compiler-llvm/src/abi/aarch64_systemv.rs b/lib/compiler-llvm/src/abi/aarch64_systemv.rs index cee33c6060d..8bcb65a008c 100644 --- a/lib/compiler-llvm/src/abi/aarch64_systemv.rs +++ b/lib/compiler-llvm/src/abi/aarch64_systemv.rs @@ -8,7 +8,7 @@ use inkwell::{ values::{BasicValue, BasicValueEnum, CallSiteValue, FunctionValue, IntValue, PointerValue}, AddressSpace, }; -use wasmer_compiler::CompileError; +use wasmer_types::CompileError; use wasmer_types::{FunctionType as FuncSig, Type}; use wasmer_vm::VMOffsets; diff --git a/lib/compiler-llvm/src/abi/mod.rs b/lib/compiler-llvm/src/abi/mod.rs index b79f9998743..1ce90cc7c07 100644 --- a/lib/compiler-llvm/src/abi/mod.rs +++ b/lib/compiler-llvm/src/abi/mod.rs @@ -14,7 +14,7 @@ use inkwell::{ types::FunctionType, values::{BasicValueEnum, CallSiteValue, FunctionValue, PointerValue}, }; -use wasmer_compiler::CompileError; +use wasmer_types::CompileError; use wasmer_types::FunctionType as FuncSig; use wasmer_vm::VMOffsets; diff --git a/lib/compiler-llvm/src/abi/x86_64_systemv.rs b/lib/compiler-llvm/src/abi/x86_64_systemv.rs index d9513d07a49..7075193080a 100644 --- a/lib/compiler-llvm/src/abi/x86_64_systemv.rs +++ b/lib/compiler-llvm/src/abi/x86_64_systemv.rs @@ -11,8 +11,7 @@ use inkwell::{ }, AddressSpace, }; -use wasmer_compiler::CompileError; -use wasmer_types::{FunctionType as FuncSig, Type}; +use wasmer_types::{CompileError, FunctionType as FuncSig, Type}; use wasmer_vm::VMOffsets; use std::convert::TryInto; diff --git a/lib/compiler-llvm/src/compiler.rs b/lib/compiler-llvm/src/compiler.rs index 6c597b468be..f57868dcd5b 100644 --- a/lib/compiler-llvm/src/compiler.rs +++ b/lib/compiler-llvm/src/compiler.rs @@ -11,12 +11,14 @@ use rayon::iter::ParallelBridge; use rayon::prelude::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator}; use std::sync::Arc; use wasmer_compiler::{ - Compilation, CompileError, CompileModuleInfo, Compiler, CustomSection, CustomSectionProtection, - Dwarf, FunctionBodyData, ModuleMiddleware, ModuleTranslationState, RelocationTarget, - SectionBody, SectionIndex, Symbol, SymbolRegistry, Target, + Compiler, FunctionBodyData, ModuleMiddleware, ModuleTranslationState, Symbol, SymbolRegistry, + Target, }; use wasmer_types::entity::{EntityRef, PrimaryMap}; -use wasmer_types::{FunctionIndex, LocalFunctionIndex, SignatureIndex}; +use wasmer_types::{ + Compilation, CompileError, CompileModuleInfo, CustomSection, CustomSectionProtection, Dwarf, + FunctionIndex, LocalFunctionIndex, RelocationTarget, SectionBody, SectionIndex, SignatureIndex, +}; //use std::sync::Mutex; diff --git a/lib/compiler-llvm/src/object_file.rs b/lib/compiler-llvm/src/object_file.rs index cc3e650979a..889ce8bcf1c 100644 --- a/lib/compiler-llvm/src/object_file.rs +++ b/lib/compiler-llvm/src/object_file.rs @@ -4,12 +4,12 @@ use std::collections::{HashMap, HashSet}; use std::convert::TryInto; use std::num::TryFromIntError; -use wasmer_compiler::{ +use wasmer_types::entity::PrimaryMap; +use wasmer_types::{ CompileError, CompiledFunctionFrameInfo, CustomSection, CustomSectionProtection, CustomSections, FunctionAddressMap, FunctionBody, InstructionAddressMap, Relocation, RelocationKind, RelocationTarget, SectionBody, SectionIndex, SourceLoc, }; -use wasmer_types::entity::PrimaryMap; use wasmer_vm::libcalls::LibCall; fn map_tryfromint_err(error: TryFromIntError) -> CompileError { @@ -21,7 +21,7 @@ fn map_object_err(error: object::read::Error) -> CompileError { } pub struct CompiledFunction { - pub compiled_function: wasmer_compiler::CompiledFunction, + pub compiled_function: wasmer_types::CompiledFunction, pub custom_sections: CustomSections, pub eh_frame_section_indices: Vec, } @@ -329,7 +329,7 @@ where }; Ok(CompiledFunction { - compiled_function: wasmer_compiler::CompiledFunction { + compiled_function: wasmer_types::CompiledFunction { body: function_body, relocations: relocations .remove_entry(&root_section_index) diff --git a/lib/compiler-llvm/src/trampoline/wasm.rs b/lib/compiler-llvm/src/trampoline/wasm.rs index b1aee66742d..c3166dd2bfe 100644 --- a/lib/compiler-llvm/src/trampoline/wasm.rs +++ b/lib/compiler-llvm/src/trampoline/wasm.rs @@ -16,8 +16,9 @@ use inkwell::{ use std::cmp; use std::convert::TryFrom; use std::convert::TryInto; -use wasmer_compiler::{CompileError, FunctionBody, RelocationTarget}; -use wasmer_types::{FunctionType, LocalFunctionIndex}; +use wasmer_types::{ + CompileError, FunctionBody, FunctionType, LocalFunctionIndex, RelocationTarget, +}; pub struct FuncTrampoline { ctx: Context, diff --git a/lib/compiler-llvm/src/translator/code.rs b/lib/compiler-llvm/src/translator/code.rs index cb4823af603..85b6edc56a3 100644 --- a/lib/compiler-llvm/src/translator/code.rs +++ b/lib/compiler-llvm/src/translator/code.rs @@ -27,13 +27,13 @@ use crate::object_file::{load_object_file, CompiledFunction}; use std::convert::TryFrom; use wasmer_compiler::wasmparser::{MemoryImmediate, Operator}; use wasmer_compiler::{ - wptype_to_type, CompileError, FunctionBinaryReader, FunctionBodyData, MiddlewareBinaryReader, - ModuleMiddlewareChain, ModuleTranslationState, RelocationTarget, Symbol, SymbolRegistry, + from_binaryreadererror_wasmerror, wptype_to_type, FunctionBinaryReader, FunctionBodyData, + MiddlewareBinaryReader, ModuleMiddlewareChain, ModuleTranslationState, Symbol, SymbolRegistry, }; use wasmer_types::entity::PrimaryMap; use wasmer_types::{ - FunctionIndex, FunctionType, GlobalIndex, LocalFunctionIndex, MemoryIndex, ModuleInfo, - SignatureIndex, TableIndex, Type, + CompileError, FunctionIndex, FunctionType, GlobalIndex, LocalFunctionIndex, MemoryIndex, + ModuleInfo, RelocationTarget, SignatureIndex, TableIndex, Type, }; use wasmer_vm::{MemoryStyle, TableStyle, VMOffsets}; @@ -1615,7 +1615,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> { .targets() .enumerate() .map(|(case_index, depth)| { - let depth = depth?; + let depth = depth.map_err(from_binaryreadererror_wasmerror)?; let frame_result: Result<&ControlFrame, CompileError> = self.state.frame_at_depth(depth); let frame = match frame_result { diff --git a/lib/compiler-llvm/src/translator/intrinsics.rs b/lib/compiler-llvm/src/translator/intrinsics.rs index 741d870ae49..9b3c6ba8be3 100644 --- a/lib/compiler-llvm/src/translator/intrinsics.rs +++ b/lib/compiler-llvm/src/translator/intrinsics.rs @@ -23,11 +23,10 @@ use inkwell::{ AddressSpace, }; use std::collections::{hash_map::Entry, HashMap}; -use wasmer_compiler::CompileError; use wasmer_types::entity::{EntityRef, PrimaryMap}; use wasmer_types::{ - FunctionIndex, FunctionType as FuncType, GlobalIndex, LocalFunctionIndex, MemoryIndex, - ModuleInfo as WasmerCompilerModule, Mutability, SignatureIndex, TableIndex, Type, + CompileError, FunctionIndex, FunctionType as FuncType, GlobalIndex, LocalFunctionIndex, + MemoryIndex, ModuleInfo as WasmerCompilerModule, Mutability, SignatureIndex, TableIndex, Type, }; use wasmer_vm::{MemoryStyle, TrapCode, VMBuiltinFunctionIndex, VMOffsets}; diff --git a/lib/compiler-llvm/src/translator/state.rs b/lib/compiler-llvm/src/translator/state.rs index b3300c19691..339d325e71c 100644 --- a/lib/compiler-llvm/src/translator/state.rs +++ b/lib/compiler-llvm/src/translator/state.rs @@ -4,7 +4,7 @@ use inkwell::{ }; use smallvec::SmallVec; use std::ops::{BitAnd, BitOr, BitOrAssign}; -use wasmer_compiler::CompileError; +use wasmer_types::CompileError; #[derive(Debug)] pub enum ControlFrame<'ctx> { diff --git a/lib/compiler-singlepass/README.md b/lib/compiler-singlepass/README.md index 4265359f378..56226839c84 100644 --- a/lib/compiler-singlepass/README.md +++ b/lib/compiler-singlepass/README.md @@ -10,7 +10,7 @@ use wasmer_compiler_singlepass::Singlepass; let compiler = Singlepass::new(); // Put it into an engine and add it to the store -let store = Store::new(&Universal::new(compiler).engine()); +let store = Store::new_with_engine(&Universal::new(compiler).engine()); ``` *Note: you can find a [full working example using Singlepass compiler diff --git a/lib/compiler-singlepass/src/address_map.rs b/lib/compiler-singlepass/src/address_map.rs index 59ce00fe91c..cc4eb6cde54 100644 --- a/lib/compiler-singlepass/src/address_map.rs +++ b/lib/compiler-singlepass/src/address_map.rs @@ -1,4 +1,5 @@ -use wasmer_compiler::{FunctionAddressMap, FunctionBodyData, InstructionAddressMap, SourceLoc}; +use wasmer_compiler::FunctionBodyData; +use wasmer_types::{FunctionAddressMap, InstructionAddressMap, SourceLoc}; pub fn get_function_address_map( instructions: Vec, diff --git a/lib/compiler-singlepass/src/codegen.rs b/lib/compiler-singlepass/src/codegen.rs index 4a5af3b79d3..d7836e55a76 100644 --- a/lib/compiler-singlepass/src/codegen.rs +++ b/lib/compiler-singlepass/src/codegen.rs @@ -11,18 +11,16 @@ use smallvec::{smallvec, SmallVec}; use std::cmp; use std::iter; use wasmer_compiler::wasmparser::{Operator, Type as WpType, TypeOrFuncType as WpTypeOrFuncType}; +use wasmer_compiler::{CallingConvention, FunctionBodyData}; #[cfg(feature = "unwind")] -use wasmer_compiler::CompiledFunctionUnwindInfo; -use wasmer_compiler::{ - CallingConvention, CompiledFunction, CompiledFunctionFrameInfo, FunctionBody, FunctionBodyData, - Relocation, RelocationTarget, SectionIndex, -}; +use wasmer_types::CompiledFunctionUnwindInfo; use wasmer_types::{ entity::{EntityRef, PrimaryMap}, FunctionIndex, FunctionType, GlobalIndex, LocalFunctionIndex, LocalMemoryIndex, MemoryIndex, - MemoryStyle, ModuleInfo, SignatureIndex, TableIndex, TableStyle, TrapCode, Type, - VMBuiltinFunctionIndex, VMOffsets, + MemoryStyle, ModuleInfo, Relocation, RelocationTarget, SectionIndex, SignatureIndex, + TableIndex, TableStyle, TrapCode, Type, VMBuiltinFunctionIndex, VMOffsets, }; +use wasmer_types::{CompiledFunction, CompiledFunctionFrameInfo, FunctionBody}; /// The singlepass per-function code generator. pub struct FuncGen<'a, M: Machine> { diff --git a/lib/compiler-singlepass/src/compiler.rs b/lib/compiler-singlepass/src/compiler.rs index b86c30fde0a..66859e81437 100644 --- a/lib/compiler-singlepass/src/compiler.rs +++ b/lib/compiler-singlepass/src/compiler.rs @@ -20,16 +20,17 @@ use gimli::write::{EhFrame, FrameTable}; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use std::sync::Arc; use wasmer_compiler::{ - Architecture, CallingConvention, Compilation, CompileError, CompileModuleInfo, - CompiledFunction, Compiler, CompilerConfig, CpuFeature, Dwarf, FunctionBinaryReader, - FunctionBody, FunctionBodyData, MiddlewareBinaryReader, ModuleMiddleware, - ModuleMiddlewareChain, ModuleTranslationState, OperatingSystem, SectionIndex, Target, - TrapInformation, + Architecture, CallingConvention, Compiler, CompilerConfig, CpuFeature, FunctionBinaryReader, + FunctionBodyData, MiddlewareBinaryReader, ModuleMiddleware, ModuleMiddlewareChain, + ModuleTranslationState, OperatingSystem, Target, }; use wasmer_types::entity::{EntityRef, PrimaryMap}; use wasmer_types::{ - FunctionIndex, FunctionType, LocalFunctionIndex, MemoryIndex, ModuleInfo, TableIndex, TrapCode, - VMOffsets, + Compilation, CompileModuleInfo, CompiledFunction, Dwarf, FunctionBody, TrapInformation, +}; +use wasmer_types::{ + CompileError, FunctionIndex, FunctionType, LocalFunctionIndex, MemoryIndex, ModuleInfo, + SectionIndex, TableIndex, TrapCode, VMOffsets, }; /// A compiler that compiles a WebAssembly module with Singlepass. diff --git a/lib/compiler-singlepass/src/dwarf.rs b/lib/compiler-singlepass/src/dwarf.rs index 07e67bbdb00..9ed288b467f 100644 --- a/lib/compiler-singlepass/src/dwarf.rs +++ b/lib/compiler-singlepass/src/dwarf.rs @@ -1,9 +1,11 @@ use gimli::write::{Address, EndianVec, Result, Writer}; use gimli::{RunTimeEndian, SectionId}; -use wasmer_compiler::{CustomSection, CustomSectionProtection, SectionBody}; -use wasmer_compiler::{Endianness, Relocation, RelocationKind, RelocationTarget}; +use wasmer_compiler::Endianness; use wasmer_types::entity::EntityRef; -use wasmer_types::LocalFunctionIndex; +use wasmer_types::{ + CustomSection, CustomSectionProtection, LocalFunctionIndex, Relocation, RelocationKind, + RelocationTarget, SectionBody, +}; #[derive(Clone, Debug)] pub struct WriterRelocate { diff --git a/lib/compiler-singlepass/src/emitter_arm64.rs b/lib/compiler-singlepass/src/emitter_arm64.rs index 24dc7ca7b3d..10edbaaeb8d 100644 --- a/lib/compiler-singlepass/src/emitter_arm64.rs +++ b/lib/compiler-singlepass/src/emitter_arm64.rs @@ -9,10 +9,9 @@ use dynasmrt::{ aarch64::Aarch64Relocation, AssemblyOffset, DynamicLabel, DynasmApi, DynasmLabelApi, VecAssembler, }; -use wasmer_compiler::{ - CallingConvention, CustomSection, CustomSectionProtection, FunctionBody, SectionBody, -}; -use wasmer_types::{FunctionIndex, FunctionType, Type, VMOffsets}; +use wasmer_compiler::CallingConvention; +use wasmer_types::{CustomSection, CustomSectionProtection, SectionBody}; +use wasmer_types::{FunctionBody, FunctionIndex, FunctionType, Type, VMOffsets}; type Assembler = VecAssembler; diff --git a/lib/compiler-singlepass/src/machine.rs b/lib/compiler-singlepass/src/machine.rs index d71d98480b3..3e6c1136b28 100644 --- a/lib/compiler-singlepass/src/machine.rs +++ b/lib/compiler-singlepass/src/machine.rs @@ -8,10 +8,9 @@ use std::collections::BTreeMap; use std::fmt::Debug; pub use wasmer_compiler::wasmparser::MemoryImmediate; use wasmer_compiler::wasmparser::Type as WpType; -use wasmer_compiler::{ - Architecture, CallingConvention, CpuFeature, CustomSection, FunctionBody, - InstructionAddressMap, Relocation, RelocationTarget, Target, TrapInformation, -}; +use wasmer_compiler::{Architecture, CallingConvention, CpuFeature, Target}; +use wasmer_types::{CustomSection, Relocation, RelocationTarget}; +use wasmer_types::{FunctionBody, InstructionAddressMap, TrapInformation}; use wasmer_types::{FunctionIndex, FunctionType, TrapCode, VMOffsets}; pub type Label = DynamicLabel; diff --git a/lib/compiler-singlepass/src/machine_arm64.rs b/lib/compiler-singlepass/src/machine_arm64.rs index 743c0619a94..e70a9515d9f 100644 --- a/lib/compiler-singlepass/src/machine_arm64.rs +++ b/lib/compiler-singlepass/src/machine_arm64.rs @@ -10,10 +10,9 @@ use dynasmrt::{aarch64::Aarch64Relocation, VecAssembler}; #[cfg(feature = "unwind")] use gimli::{write::CallFrameInstruction, AArch64}; use wasmer_compiler::wasmparser::Type as WpType; -use wasmer_compiler::{ - CallingConvention, CustomSection, FunctionBody, InstructionAddressMap, Relocation, - RelocationKind, RelocationTarget, SourceLoc, TrapInformation, -}; +use wasmer_compiler::CallingConvention; +use wasmer_types::{CustomSection, Relocation, RelocationKind, RelocationTarget}; +use wasmer_types::{FunctionBody, InstructionAddressMap, SourceLoc, TrapInformation}; use wasmer_types::{FunctionIndex, FunctionType, TrapCode, VMOffsets}; type Assembler = VecAssembler; diff --git a/lib/compiler-singlepass/src/machine_x64.rs b/lib/compiler-singlepass/src/machine_x64.rs index 83bd1af147f..66ac19d648b 100644 --- a/lib/compiler-singlepass/src/machine_x64.rs +++ b/lib/compiler-singlepass/src/machine_x64.rs @@ -13,11 +13,12 @@ use dynasmrt::{x64::X64Relocation, DynasmError, VecAssembler}; use gimli::{write::CallFrameInstruction, X86_64}; use std::ops::{Deref, DerefMut}; use wasmer_compiler::wasmparser::Type as WpType; -use wasmer_compiler::{ - CallingConvention, CpuFeature, CustomSection, CustomSectionProtection, FunctionBody, - InstructionAddressMap, Relocation, RelocationKind, RelocationTarget, SectionBody, SourceLoc, - TrapInformation, +use wasmer_compiler::{CallingConvention, CpuFeature}; +use wasmer_types::{ + CustomSection, CustomSectionProtection, Relocation, RelocationKind, RelocationTarget, + SectionBody, }; +use wasmer_types::{FunctionBody, InstructionAddressMap, SourceLoc, TrapInformation}; use wasmer_types::{FunctionIndex, FunctionType, TrapCode, Type, VMOffsets}; type Assembler = VecAssembler; diff --git a/lib/compiler/Cargo.toml b/lib/compiler/Cargo.toml index 9251f1967b6..110308ae966 100644 --- a/lib/compiler/Cargo.toml +++ b/lib/compiler/Cargo.toml @@ -20,18 +20,35 @@ serde = { version = "1.0", features = ["derive"], optional = true } thiserror = "1.0" serde_bytes = { version = "0.11", optional = true } smallvec = "1.6" -rkyv = { version = "0.7.20", optional = true } +rkyv = { version = "0.7.38", features = ["indexmap"] } + +backtrace = "0.3" +rustc-demangle = "0.1" +memmap2 = "0.5" +more-asserts = "0.2" +lazy_static = "1.4" + +cfg-if = "1.0" +leb128 = "0.2" +enum-iterator = "0.7.0" + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +wasmer-vm = { path = "../vm", version = "=2.3.0" } +region = { version = "3.0" } + +[target.'cfg(target_os = "windows")'.dependencies] +winapi = { version = "0.3", features = ["winnt", "impl-default"] } [features] -default = ["std", "enable-serde", "enable-rkyv"] +default = ["std", "enable-serde" ] # This feature is for compiler implementors, it enables using `Compiler` and # `CompilerConfig`, as well as the included wasmparser. # Disable this feature if you just want a headless engine. translator = ["wasmparser"] +universal_engine = [] std = ["wasmer-types/std"] core = ["hashbrown", "wasmer-types/core"] enable-serde = ["serde", "serde_bytes", "wasmer-types/enable-serde"] -enable-rkyv = ["rkyv", "wasmer-types/enable-rkyv"] [badges] maintenance = { status = "experimental" } diff --git a/lib/artifact/src/artifact.rs b/lib/compiler/src/artifact.rs similarity index 97% rename from lib/artifact/src/artifact.rs rename to lib/compiler/src/artifact.rs index 043dcce86f8..a6ac0f97029 100644 --- a/lib/artifact/src/artifact.rs +++ b/lib/compiler/src/artifact.rs @@ -1,12 +1,14 @@ -use crate::{DeserializeError, SerializeError}; +//! Generic Artifact abstraction for Wasmer Engines. + +use crate::{CpuFeature, Features}; use enumset::EnumSet; use std::any::Any; use std::convert::TryInto; use std::path::Path; use std::sync::Arc; use std::{fs, mem}; -use wasmer_compiler::{CpuFeature, Features}; use wasmer_types::entity::PrimaryMap; +use wasmer_types::{DeserializeError, SerializeError}; use wasmer_types::{ MemoryIndex, MemoryStyle, ModuleInfo, OwnedDataInitializer, TableIndex, TableStyle, }; diff --git a/lib/compiler/src/compiler.rs b/lib/compiler/src/compiler.rs index 37a49a88725..90378510863 100644 --- a/lib/compiler/src/compiler.rs +++ b/lib/compiler/src/compiler.rs @@ -1,17 +1,17 @@ //! This module mainly outputs the `Compiler` trait that custom //! compilers will need to implement. -use crate::error::CompileError; -use crate::function::Compilation; use crate::lib::std::boxed::Box; use crate::lib::std::sync::Arc; -use crate::module::CompileModuleInfo; use crate::target::Target; use crate::translator::ModuleMiddleware; use crate::FunctionBodyData; use crate::ModuleTranslationState; -use crate::SectionIndex; +use wasmer_types::compilation::function::Compilation; +use wasmer_types::compilation::module::CompileModuleInfo; use wasmer_types::entity::PrimaryMap; +use wasmer_types::error::CompileError; +use wasmer_types::SectionIndex; use wasmer_types::{Features, FunctionIndex, LocalFunctionIndex, SignatureIndex}; use wasmparser::{Validator, WasmFeatures}; diff --git a/lib/engine/src/artifact.rs b/lib/compiler/src/engine/artifact.rs similarity index 97% rename from lib/engine/src/artifact.rs rename to lib/compiler/src/engine/artifact.rs index edd0af01183..158247979f7 100644 --- a/lib/engine/src/artifact.rs +++ b/lib/compiler/src/engine/artifact.rs @@ -1,8 +1,7 @@ +use crate::CpuFeature; use crate::{resolve_imports, Export, InstantiationError, RuntimeError, Tunables}; +use crate::{ArtifactCreate, Upcastable}; use std::any::Any; -pub use wasmer_artifact::MetadataHeader; -use wasmer_artifact::{ArtifactCreate, Upcastable}; -use wasmer_compiler::CpuFeature; use wasmer_types::entity::BoxedSlice; use wasmer_types::{DataInitializer, FunctionIndex, LocalFunctionIndex, SignatureIndex}; use wasmer_vm::{ diff --git a/lib/engine/src/error.rs b/lib/compiler/src/engine/error.rs similarity index 93% rename from lib/engine/src/error.rs rename to lib/compiler/src/engine/error.rs index fc377849c01..a1489585bbb 100644 --- a/lib/engine/src/error.rs +++ b/lib/compiler/src/engine/error.rs @@ -1,7 +1,7 @@ //! The WebAssembly possible errors -use crate::trap::RuntimeError; +use crate::engine::trap::RuntimeError; use thiserror::Error; -pub use wasmer_artifact::{DeserializeError, ImportError, SerializeError}; +pub use wasmer_types::{DeserializeError, ImportError, SerializeError}; /// The WebAssembly.LinkError object indicates an error during /// module instantiation (besides traps from the start function). diff --git a/lib/engine/src/export.rs b/lib/compiler/src/engine/export.rs similarity index 100% rename from lib/engine/src/export.rs rename to lib/compiler/src/engine/export.rs diff --git a/lib/engine/src/engine.rs b/lib/compiler/src/engine/inner.rs similarity index 94% rename from lib/engine/src/engine.rs rename to lib/compiler/src/engine/inner.rs index 28779df671b..7b5772ad038 100644 --- a/lib/engine/src/engine.rs +++ b/lib/compiler/src/engine/inner.rs @@ -1,13 +1,13 @@ //! Engine trait and associated types. -use crate::tunables::Tunables; -use crate::{Artifact, DeserializeError}; +use crate::engine::tunables::Tunables; +use crate::Artifact; +use crate::Target; use memmap2::Mmap; use std::path::Path; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use std::sync::Arc; -use wasmer_compiler::{CompileError, Target}; -use wasmer_types::FunctionType; +use wasmer_types::{CompileError, DeserializeError, FunctionType}; use wasmer_vm::{VMCallerCheckedAnyfunc, VMFuncRef, VMSharedSignatureIndex}; /// A unimplemented Wasmer `Engine`. diff --git a/lib/compiler/src/engine/mod.rs b/lib/compiler/src/engine/mod.rs new file mode 100644 index 00000000000..d01881fb203 --- /dev/null +++ b/lib/compiler/src/engine/mod.rs @@ -0,0 +1,23 @@ +//! Generic Engine abstraction for Wasmer Engines. + +mod artifact; +mod error; +mod export; +mod inner; +mod resolver; +mod trap; +mod tunables; + +#[cfg(feature = "translator")] +mod universal; + +pub use self::artifact::Artifact; +pub use self::error::{InstantiationError, LinkError}; +pub use self::export::{Export, ExportFunction, ExportFunctionMetadata}; +pub use self::inner::{Engine, EngineId}; +pub use self::resolver::resolve_imports; +pub use self::trap::*; +pub use self::tunables::Tunables; + +#[cfg(feature = "translator")] +pub use self::universal::*; diff --git a/lib/engine/src/resolver.rs b/lib/compiler/src/engine/resolver.rs similarity index 98% rename from lib/engine/src/resolver.rs rename to lib/compiler/src/engine/resolver.rs index e78d16db888..3e8c1656e3a 100644 --- a/lib/engine/src/resolver.rs +++ b/lib/compiler/src/engine/resolver.rs @@ -1,9 +1,11 @@ //! Custom resolution for external references. -use crate::{Export, ExportFunctionMetadata, ImportError, LinkError}; +use crate::{Export, ExportFunctionMetadata, LinkError}; use more_asserts::assert_ge; use wasmer_types::entity::{BoxedSlice, EntityRef, PrimaryMap}; -use wasmer_types::{ExternType, FunctionIndex, ImportIndex, MemoryIndex, ModuleInfo, TableIndex}; +use wasmer_types::{ + ExternType, FunctionIndex, ImportError, ImportIndex, MemoryIndex, ModuleInfo, TableIndex, +}; use wasmer_vm::{ FunctionBodyPtr, ImportFunctionEnv, Imports, MemoryStyle, TableStyle, VMFunctionBody, diff --git a/lib/engine/src/trap/error.rs b/lib/compiler/src/engine/trap/error.rs similarity index 99% rename from lib/engine/src/trap/error.rs rename to lib/compiler/src/engine/trap/error.rs index 4a62f2eb0ec..e2c26c031be 100644 --- a/lib/engine/src/trap/error.rs +++ b/lib/compiler/src/engine/trap/error.rs @@ -50,7 +50,7 @@ impl RuntimeError { /// /// # Example /// ``` - /// let trap = wasmer_engine::RuntimeError::new("unexpected error"); + /// let trap = wasmer_compiler::RuntimeError::new("unexpected error"); /// assert_eq!("unexpected error", trap.message()); /// ``` pub fn new>(message: I) -> Self { diff --git a/lib/engine/src/trap/frame_info.rs b/lib/compiler/src/engine/trap/frame_info.rs similarity index 99% rename from lib/engine/src/trap/frame_info.rs rename to lib/compiler/src/engine/trap/frame_info.rs index 44dd52d78e6..207b4cfd831 100644 --- a/lib/engine/src/trap/frame_info.rs +++ b/lib/compiler/src/engine/trap/frame_info.rs @@ -14,8 +14,8 @@ use std::cmp; use std::collections::BTreeMap; use std::sync::{Arc, RwLock}; -use wasmer_compiler::{CompiledFunctionFrameInfo, SourceLoc, TrapInformation}; use wasmer_types::entity::{BoxedSlice, EntityRef, PrimaryMap}; +use wasmer_types::{CompiledFunctionFrameInfo, SourceLoc, TrapInformation}; use wasmer_types::{LocalFunctionIndex, ModuleInfo}; use wasmer_vm::FunctionBodyPtr; diff --git a/lib/engine/src/trap/mod.rs b/lib/compiler/src/engine/trap/mod.rs similarity index 100% rename from lib/engine/src/trap/mod.rs rename to lib/compiler/src/engine/trap/mod.rs diff --git a/lib/engine/src/tunables.rs b/lib/compiler/src/engine/tunables.rs similarity index 99% rename from lib/engine/src/tunables.rs rename to lib/compiler/src/engine/tunables.rs index f07d5a78ba3..3fc01cc6292 100644 --- a/lib/engine/src/tunables.rs +++ b/lib/compiler/src/engine/tunables.rs @@ -1,4 +1,4 @@ -use crate::error::LinkError; +use crate::engine::error::LinkError; use std::ptr::NonNull; use std::sync::Arc; use wasmer_types::entity::{EntityRef, PrimaryMap}; diff --git a/lib/engine-universal/src/artifact.rs b/lib/compiler/src/engine/universal/artifact.rs similarity index 92% rename from lib/engine-universal/src/artifact.rs rename to lib/compiler/src/engine/universal/artifact.rs index 32cba6b9d7a..1ad5f86afc5 100644 --- a/lib/engine-universal/src/artifact.rs +++ b/lib/compiler/src/engine/universal/artifact.rs @@ -1,25 +1,22 @@ //! Define `UniversalArtifact`, based on `UniversalArtifactBuild` //! to allow compiling and instantiating to be done as separate steps. -use crate::engine::{UniversalEngine, UniversalEngineInner}; -use crate::link::link_module; +use super::engine::{UniversalEngine, UniversalEngineInner}; +use crate::engine::universal::link::link_module; +use crate::ArtifactCreate; +use crate::{ + register_frame_info, Artifact, FunctionExtent, GlobalFrameInfoRegistration, MetadataHeader, +}; +use crate::{CpuFeature, Features, Triple}; +#[cfg(feature = "universal_engine")] +use crate::{Engine, ModuleEnvironment, Tunables}; +use crate::{SerializableModule, UniversalArtifactBuild}; use enumset::EnumSet; use std::sync::{Arc, Mutex}; -#[cfg(feature = "compiler")] -use wasmer_compiler::ModuleEnvironment; -use wasmer_compiler::{CompileError, CpuFeature, Features, Triple}; -use wasmer_engine::{ - register_frame_info, Artifact, DeserializeError, FunctionExtent, GlobalFrameInfoRegistration, - MetadataHeader, SerializeError, -}; -#[cfg(feature = "compiler")] -use wasmer_engine::{Engine, Tunables}; -use wasmer_engine_universal_artifact::ArtifactCreate; -use wasmer_engine_universal_artifact::{SerializableModule, UniversalArtifactBuild}; use wasmer_types::entity::{BoxedSlice, PrimaryMap}; use wasmer_types::{ - FunctionIndex, LocalFunctionIndex, MemoryIndex, ModuleInfo, OwnedDataInitializer, - SignatureIndex, TableIndex, + CompileError, DeserializeError, FunctionIndex, LocalFunctionIndex, MemoryIndex, ModuleInfo, + OwnedDataInitializer, SerializeError, SignatureIndex, TableIndex, }; use wasmer_vm::{ FuncDataRegistry, FunctionBodyPtr, MemoryStyle, TableStyle, VMSharedSignatureIndex, @@ -40,7 +37,7 @@ pub struct UniversalArtifact { impl UniversalArtifact { /// Compile a data buffer into a `UniversalArtifactBuild`, which may then be instantiated. - #[cfg(feature = "compiler")] + #[cfg(feature = "universal_engine")] pub fn new( engine: &UniversalEngine, data: &[u8], @@ -73,7 +70,7 @@ impl UniversalArtifact { } /// Compile a data buffer into a `UniversalArtifactBuild`, which may then be instantiated. - #[cfg(not(feature = "compiler"))] + #[cfg(not(feature = "universal_engine"))] pub fn new(_engine: &UniversalEngine, _data: &[u8]) -> Result { Err(CompileError::Codegen( "Compilation is not enabled in the engine".to_string(), diff --git a/lib/engine-universal/src/builder.rs b/lib/compiler/src/engine/universal/builder.rs similarity index 91% rename from lib/engine-universal/src/builder.rs rename to lib/compiler/src/engine/universal/builder.rs index 0dd9fc0ef87..b5c80f64fd3 100644 --- a/lib/engine-universal/src/builder.rs +++ b/lib/compiler/src/engine/universal/builder.rs @@ -1,5 +1,5 @@ -use crate::UniversalEngine; -use wasmer_compiler::{CompilerConfig, Features, Target}; +use super::UniversalEngine; +use crate::{CompilerConfig, Features, Target}; /// The Universal builder pub struct Universal { @@ -44,7 +44,7 @@ impl Universal { } /// Build the `UniversalEngine` for this configuration - #[cfg(feature = "compiler")] + #[cfg(feature = "universal_engine")] pub fn engine(self) -> UniversalEngine { let target = self.target.unwrap_or_default(); if let Some(compiler_config) = self.compiler_config { @@ -59,7 +59,7 @@ impl Universal { } /// Build the `UniversalEngine` for this configuration - #[cfg(not(feature = "compiler"))] + #[cfg(not(feature = "universal_engine"))] pub fn engine(self) -> UniversalEngine { UniversalEngine::headless() } diff --git a/lib/engine-universal/src/code_memory.rs b/lib/compiler/src/engine/universal/code_memory.rs similarity index 98% rename from lib/engine-universal/src/code_memory.rs rename to lib/compiler/src/engine/universal/code_memory.rs index f2165f9444b..9c033347032 100644 --- a/lib/engine-universal/src/code_memory.rs +++ b/lib/compiler/src/engine/universal/code_memory.rs @@ -2,8 +2,8 @@ // Attributions: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md //! Memory management for executable code. -use crate::unwind::UnwindRegistry; -use wasmer_compiler::{CompiledFunctionUnwindInfo, CustomSection, FunctionBody}; +use super::unwind::UnwindRegistry; +use wasmer_types::{CompiledFunctionUnwindInfo, CustomSection, FunctionBody}; use wasmer_vm::{Mmap, VMFunctionBody}; /// The optimal alignment for functions. diff --git a/lib/engine-universal/src/engine.rs b/lib/compiler/src/engine/universal/engine.rs similarity index 94% rename from lib/engine-universal/src/engine.rs rename to lib/compiler/src/engine/universal/engine.rs index f1676a9ffa8..28e4281492e 100644 --- a/lib/engine-universal/src/engine.rs +++ b/lib/compiler/src/engine/universal/engine.rs @@ -1,18 +1,19 @@ //! Universal compilation. +#[cfg(feature = "universal_engine")] +use crate::Compiler; +use crate::Target; +use crate::UniversalEngineBuilder; +use crate::{Artifact, Engine, EngineId, FunctionExtent, Tunables}; use crate::{CodeMemory, UniversalArtifact}; use std::sync::{Arc, Mutex}; -#[cfg(feature = "compiler")] -use wasmer_compiler::Compiler; -use wasmer_compiler::{ - CompileError, CustomSection, CustomSectionProtection, FunctionBody, SectionIndex, Target, -}; -use wasmer_engine::{Artifact, DeserializeError, Engine, EngineId, FunctionExtent, Tunables}; -use wasmer_engine_universal_artifact::UniversalEngineBuilder; use wasmer_types::entity::PrimaryMap; +use wasmer_types::FunctionBody; use wasmer_types::{ - Features, FunctionIndex, FunctionType, LocalFunctionIndex, ModuleInfo, SignatureIndex, + CompileError, DeserializeError, Features, FunctionIndex, FunctionType, LocalFunctionIndex, + ModuleInfo, SignatureIndex, }; +use wasmer_types::{CustomSection, CustomSectionProtection, SectionIndex}; use wasmer_vm::{ FuncDataRegistry, FunctionBodyPtr, SectionBodyPtr, SignatureRegistry, VMCallerCheckedAnyfunc, VMFuncRef, VMFunctionBody, VMSharedSignatureIndex, VMTrampoline, @@ -29,7 +30,7 @@ pub struct UniversalEngine { impl UniversalEngine { /// Create a new `UniversalEngine` with the given config - #[cfg(feature = "compiler")] + #[cfg(feature = "universal_engine")] pub fn new(compiler: Box, target: Target, features: Features) -> Self { Self { inner: Arc::new(Mutex::new(UniversalEngineInner { @@ -107,7 +108,7 @@ impl Engine for UniversalEngine { } /// Compile a WebAssembly binary - #[cfg(feature = "compiler")] + #[cfg(feature = "universal_engine")] fn compile( &self, binary: &[u8], @@ -117,7 +118,7 @@ impl Engine for UniversalEngine { } /// Compile a WebAssembly binary - #[cfg(not(feature = "compiler"))] + #[cfg(not(feature = "universal_engine"))] fn compile( &self, _binary: &[u8], @@ -161,7 +162,7 @@ pub struct UniversalEngineInner { impl UniversalEngineInner { /// Gets the compiler associated to this engine. - #[cfg(feature = "compiler")] + #[cfg(feature = "universal_engine")] pub fn compiler(&self) -> Result<&dyn Compiler, CompileError> { self.builder.compiler() } diff --git a/lib/engine-universal/src/link.rs b/lib/compiler/src/engine/universal/link.rs similarity index 95% rename from lib/engine-universal/src/link.rs rename to lib/compiler/src/engine/universal/link.rs index 757c8c1867e..713908a22fc 100644 --- a/lib/engine-universal/src/link.rs +++ b/lib/compiler/src/engine/universal/link.rs @@ -1,11 +1,11 @@ //! Linking for Universal-compiled code. +use crate::get_libcall_trampoline; +use crate::FunctionExtent; use std::ptr::{read_unaligned, write_unaligned}; -use wasmer_compiler::{Relocation, RelocationKind, RelocationTarget, Relocations, SectionIndex}; -use wasmer_engine::FunctionExtent; -use wasmer_engine_universal_artifact::get_libcall_trampoline; use wasmer_types::entity::PrimaryMap; use wasmer_types::{LocalFunctionIndex, ModuleInfo}; +use wasmer_types::{Relocation, RelocationKind, RelocationTarget, Relocations, SectionIndex}; use wasmer_vm::libcalls::function_pointer; use wasmer_vm::SectionBodyPtr; diff --git a/lib/compiler/src/engine/universal/mod.rs b/lib/compiler/src/engine/universal/mod.rs new file mode 100644 index 00000000000..d906828439d --- /dev/null +++ b/lib/compiler/src/engine/universal/mod.rs @@ -0,0 +1,18 @@ +//! Universal backend for Wasmer compilers. +//! +//! Given a compiler (such as `CraneliftCompiler` or `LLVMCompiler`) +//! it generates the compiled machine code, and publishes it into +//! memory so it can be used externally. + +mod artifact; +mod builder; +mod code_memory; +mod engine; +mod link; +mod unwind; + +pub use self::artifact::UniversalArtifact; +pub use self::builder::Universal; +pub use self::code_memory::CodeMemory; +pub use self::engine::UniversalEngine; +pub use self::link::link_module; diff --git a/lib/engine-universal/src/serialize.rs b/lib/compiler/src/engine/universal/serialize.rs similarity index 98% rename from lib/engine-universal/src/serialize.rs rename to lib/compiler/src/engine/universal/serialize.rs index 96847ae4896..9c5068c586b 100644 --- a/lib/engine-universal/src/serialize.rs +++ b/lib/compiler/src/engine/universal/serialize.rs @@ -1,13 +1,13 @@ +use crate::{ + CompileModuleInfo, CompiledFunctionFrameInfo, CustomSection, Dwarf, FunctionBody, Relocation, + SectionIndex, +}; +use crate::{DeserializeError, SerializeError}; use rkyv::{ archived_value, de::deserializers::SharedDeserializeMap, ser::serializers::AllocSerializer, ser::Serializer as RkyvSerializer, Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize, }; -use wasmer_compiler::{ - CompileModuleInfo, CompiledFunctionFrameInfo, CustomSection, Dwarf, FunctionBody, Relocation, - SectionIndex, -}; -use wasmer_engine::{DeserializeError, SerializeError}; use wasmer_types::entity::PrimaryMap; use wasmer_types::{FunctionIndex, LocalFunctionIndex, OwnedDataInitializer, SignatureIndex}; diff --git a/lib/engine-universal/src/unwind/dummy.rs b/lib/compiler/src/engine/universal/unwind/dummy.rs similarity index 94% rename from lib/engine-universal/src/unwind/dummy.rs rename to lib/compiler/src/engine/universal/unwind/dummy.rs index 3d029ecd981..0a34e29fd56 100644 --- a/lib/engine-universal/src/unwind/dummy.rs +++ b/lib/compiler/src/engine/universal/unwind/dummy.rs @@ -1,6 +1,6 @@ //! Module for Dummy unwind registry. -use wasmer_compiler::CompiledFunctionUnwindInfo; +use wasmer_types::CompiledFunctionUnwindInfo; /// Represents a registry of function unwind information when the host system /// support any one in specific. diff --git a/lib/engine-universal/src/unwind/mod.rs b/lib/compiler/src/engine/universal/unwind/mod.rs similarity index 100% rename from lib/engine-universal/src/unwind/mod.rs rename to lib/compiler/src/engine/universal/unwind/mod.rs diff --git a/lib/engine-universal/src/unwind/systemv.rs b/lib/compiler/src/engine/universal/unwind/systemv.rs similarity index 98% rename from lib/engine-universal/src/unwind/systemv.rs rename to lib/compiler/src/engine/universal/unwind/systemv.rs index d2c43968a69..1b2cd180d6a 100644 --- a/lib/engine-universal/src/unwind/systemv.rs +++ b/lib/compiler/src/engine/universal/unwind/systemv.rs @@ -3,7 +3,7 @@ //! Module for System V ABI unwind registry. -use wasmer_compiler::CompiledFunctionUnwindInfo; +use wasmer_types::CompiledFunctionUnwindInfo; /// Represents a registry of function unwind information for System V ABI. pub struct UnwindRegistry { diff --git a/lib/engine-universal/src/unwind/windows_x64.rs b/lib/compiler/src/engine/universal/unwind/windows_x64.rs similarity index 98% rename from lib/engine-universal/src/unwind/windows_x64.rs rename to lib/compiler/src/engine/universal/unwind/windows_x64.rs index 8ee3903b32f..d5cde49d25d 100644 --- a/lib/engine-universal/src/unwind/windows_x64.rs +++ b/lib/compiler/src/engine/universal/unwind/windows_x64.rs @@ -3,7 +3,7 @@ //! Module for Windows x64 ABI unwind registry. use std::collections::HashMap; -use wasmer_compiler::CompiledFunctionUnwindInfo; +use wasmer_types::CompiledFunctionUnwindInfo; use winapi::um::winnt; /// Represents a registry of function unwind information for Windows x64 ABI. diff --git a/lib/compiler/src/lib.rs b/lib/compiler/src/lib.rs index d70e1a8521a..d018fcf8257 100644 --- a/lib/compiler/src/lib.rs +++ b/lib/compiler/src/lib.rs @@ -9,7 +9,10 @@ #![warn(unused_import_braces)] #![cfg_attr(feature = "std", deny(unstable_features))] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))] +#![cfg_attr( + feature = "cargo-clippy", + allow(clippy::new_without_default, clippy::upper_case_acronyms) +)] #![cfg_attr( feature = "cargo-clippy", warn( @@ -48,60 +51,45 @@ mod lib { } } -mod address_map; +mod artifact; +#[cfg(not(target_arch = "wasm32"))] +mod engine; + +pub use crate::artifact::*; +#[cfg(not(target_arch = "wasm32"))] +pub use crate::engine::*; + +#[cfg(feature = "translator")] +mod universal_artifact; + +#[cfg(feature = "translator")] +pub use self::universal_artifact::*; + #[cfg(feature = "translator")] mod compiler; -mod error; -mod function; -mod module; -mod relocation; mod target; -mod trap; -mod unwind; + #[cfg(feature = "translator")] #[macro_use] mod translator; -mod section; -mod sourceloc; - -pub use crate::address_map::{FunctionAddressMap, InstructionAddressMap}; #[cfg(feature = "translator")] pub use crate::compiler::{Compiler, CompilerConfig, Symbol, SymbolRegistry}; -pub use crate::error::{ - CompileError, MiddlewareError, ParseCpuFeatureError, WasmError, WasmResult, -}; -pub use crate::function::{ - Compilation, CompiledFunction, CompiledFunctionFrameInfo, CustomSections, Dwarf, FunctionBody, - Functions, -}; -pub use crate::module::CompileModuleInfo; -pub use crate::relocation::{Relocation, RelocationKind, RelocationTarget, Relocations}; -pub use crate::section::{CustomSection, CustomSectionProtection, SectionBody, SectionIndex}; -pub use crate::sourceloc::SourceLoc; pub use crate::target::{ Architecture, BinaryFormat, CallingConvention, CpuFeature, Endianness, OperatingSystem, PointerWidth, Target, Triple, }; #[cfg(feature = "translator")] pub use crate::translator::{ - translate_module, wptype_to_type, FunctionBinaryReader, FunctionBodyData, FunctionMiddleware, - MiddlewareBinaryReader, MiddlewareReaderState, ModuleEnvironment, ModuleMiddleware, - ModuleMiddlewareChain, ModuleTranslationState, + from_binaryreadererror_wasmerror, translate_module, wptype_to_type, FunctionBinaryReader, + FunctionBodyData, FunctionMiddleware, MiddlewareBinaryReader, MiddlewareReaderState, + ModuleEnvironment, ModuleMiddleware, ModuleMiddlewareChain, ModuleTranslationState, }; -pub use crate::trap::TrapInformation; -pub use crate::unwind::CompiledFunctionUnwindInfo; -pub use wasmer_types::Features; +pub use wasmer_types::{Addend, CodeOffset, Features}; #[cfg(feature = "translator")] /// wasmparser is exported as a module to slim compiler dependencies pub use wasmparser; -/// Offset in bytes from the beginning of the function. -pub type CodeOffset = u32; - -/// Addend to add to the symbol value. -pub type Addend = i64; - /// Version number of this crate. pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/lib/compiler/src/target.rs b/lib/compiler/src/target.rs index e2025d4a4b5..2641d7763ae 100644 --- a/lib/compiler/src/target.rs +++ b/lib/compiler/src/target.rs @@ -7,7 +7,6 @@ // See https://github.com/rust-lang/rust-clippy/issues/6902 #![allow(clippy::use_self)] -use crate::error::ParseCpuFeatureError; use crate::lib::std::str::FromStr; use crate::lib::std::string::{String, ToString}; use enumset::{EnumSet, EnumSetType}; @@ -15,6 +14,7 @@ pub use target_lexicon::{ Architecture, BinaryFormat, CallingConvention, Endianness, OperatingSystem, PointerWidth, Triple, }; +use wasmer_types::error::ParseCpuFeatureError; /// The nomenclature is inspired by the [`cpuid` crate]. /// The list of supported features was initially retrieved from diff --git a/lib/compiler/src/translator/environ.rs b/lib/compiler/src/translator/environ.rs index 73829bad898..cc42e5f3f58 100644 --- a/lib/compiler/src/translator/environ.rs +++ b/lib/compiler/src/translator/environ.rs @@ -6,7 +6,6 @@ use crate::lib::std::string::ToString; use crate::lib::std::{boxed::Box, string::String, vec::Vec}; use crate::translate_module; use crate::wasmparser::{Operator, Range, Type}; -use crate::{WasmError, WasmResult}; use std::convert::{TryFrom, TryInto}; use std::sync::Arc; use wasmer_types::entity::PrimaryMap; @@ -17,6 +16,7 @@ use wasmer_types::{ LocalFunctionIndex, MemoryIndex, MemoryType, ModuleInfo, SignatureIndex, TableIndex, TableInitializer, TableType, }; +use wasmer_types::{WasmError, WasmResult}; /// Contains function data: bytecode and its offset in the module. #[derive(Hash)] diff --git a/lib/compiler/src/translator/error.rs b/lib/compiler/src/translator/error.rs index 07a6397d552..c11bd6f6e62 100644 --- a/lib/compiler/src/translator/error.rs +++ b/lib/compiler/src/translator/error.rs @@ -1,28 +1,26 @@ -use crate::{CompileError, WasmError}; +use wasmer_types::{CompileError, WasmError}; use wasmparser::BinaryReaderError; /// Return an `Err(WasmError::Unsupported(msg))` where `msg` the string built by calling `format!` /// on the arguments to this macro. #[macro_export] macro_rules! wasm_unsupported { - ($($arg:tt)*) => { $crate::WasmError::Unsupported(format!($($arg)*)) } + ($($arg:tt)*) => { wasmer_types::WasmError::Unsupported(format!($($arg)*)) } } -impl From for WasmError { - fn from(original: BinaryReaderError) -> Self { - Self::InvalidWebAssembly { - message: original.message().into(), - offset: original.offset(), - } +/// +pub fn from_binaryreadererror_wasmerror(original: BinaryReaderError) -> WasmError { + WasmError::InvalidWebAssembly { + message: original.message().into(), + offset: original.offset(), } } -impl From for CompileError { - fn from(original: BinaryReaderError) -> Self { - // `From` does not seem to be transitive by default, so we convert - // BinaryReaderError -> WasmError -> CompileError - Self::from(WasmError::from(original)) - } +/// +#[allow(dead_code)] +pub fn from_binaryreadererror_compileerror(original: BinaryReaderError) -> CompileError { + // BinaryReaderError -> WasmError -> CompileError + CompileError::Wasm(from_binaryreadererror_wasmerror(original)) } #[cfg(test)] @@ -34,7 +32,7 @@ mod tests { fn can_convert_binary_reader_error_to_wasm_error() { let mut reader = BinaryReader::new(b"\0\0\0\0"); let binary_reader_error = reader.read_bytes(10).unwrap_err(); - match WasmError::from(binary_reader_error) { + match from_binaryreadererror_wasmerror(binary_reader_error) { WasmError::InvalidWebAssembly { message, offset } => { assert_eq!(message, "Unexpected EOF"); assert_eq!(offset, 0); @@ -47,7 +45,7 @@ mod tests { fn can_convert_binary_reader_error_to_compile_error() { let mut reader = BinaryReader::new(b"\0\0\0\0"); let binary_reader_error = reader.read_bytes(10).unwrap_err(); - match CompileError::from(binary_reader_error) { + match from_binaryreadererror_compileerror(binary_reader_error) { CompileError::Wasm(WasmError::InvalidWebAssembly { message, offset }) => { assert_eq!(message, "Unexpected EOF"); assert_eq!(offset, 0); diff --git a/lib/compiler/src/translator/middleware.rs b/lib/compiler/src/translator/middleware.rs index b12541980f6..5e1329b238e 100644 --- a/lib/compiler/src/translator/middleware.rs +++ b/lib/compiler/src/translator/middleware.rs @@ -5,10 +5,10 @@ use smallvec::SmallVec; use std::collections::VecDeque; use std::fmt::Debug; use std::ops::Deref; -use wasmer_types::{LocalFunctionIndex, ModuleInfo}; +use wasmer_types::{LocalFunctionIndex, MiddlewareError, ModuleInfo, WasmResult}; use wasmparser::{BinaryReader, Operator, Range, Type}; -use crate::error::{MiddlewareError, WasmResult}; +use super::error::from_binaryreadererror_wasmerror; use crate::translator::environ::FunctionBinaryReader; /// A shared builder for function middlewares. @@ -131,24 +131,43 @@ impl<'a> MiddlewareBinaryReader<'a> { impl<'a> FunctionBinaryReader<'a> for MiddlewareBinaryReader<'a> { fn read_local_count(&mut self) -> WasmResult { - Ok(self.state.inner.read_var_u32()?) + self.state + .inner + .read_var_u32() + .map_err(from_binaryreadererror_wasmerror) } fn read_local_decl(&mut self) -> WasmResult<(u32, Type)> { - let count = self.state.inner.read_var_u32()?; - let ty = self.state.inner.read_type()?; + let count = self + .state + .inner + .read_var_u32() + .map_err(from_binaryreadererror_wasmerror)?; + let ty = self + .state + .inner + .read_type() + .map_err(from_binaryreadererror_wasmerror)?; Ok((count, ty)) } fn read_operator(&mut self) -> WasmResult> { if self.chain.is_empty() { // We short-circuit in case no chain is used - return Ok(self.state.inner.read_operator()?); + return self + .state + .inner + .read_operator() + .map_err(from_binaryreadererror_wasmerror); } // Try to fill the `self.pending_operations` buffer, until it is non-empty. while self.state.pending_operations.is_empty() { - let raw_op = self.state.inner.read_operator()?; + let raw_op = self + .state + .inner + .read_operator() + .map_err(from_binaryreadererror_wasmerror)?; // Fill the initial raw operator into pending buffer. self.state.pending_operations.push_back(raw_op); diff --git a/lib/compiler/src/translator/mod.rs b/lib/compiler/src/translator/mod.rs index a3d6b4b6026..eaa2425ce4c 100644 --- a/lib/compiler/src/translator/mod.rs +++ b/lib/compiler/src/translator/mod.rs @@ -21,3 +21,4 @@ pub use self::middleware::{ pub use self::module::translate_module; pub use self::sections::wptype_to_type; pub use self::state::ModuleTranslationState; +pub use error::from_binaryreadererror_wasmerror; diff --git a/lib/compiler/src/translator/module.rs b/lib/compiler/src/translator/module.rs index 6f2a3e80627..daf58f7005e 100644 --- a/lib/compiler/src/translator/module.rs +++ b/lib/compiler/src/translator/module.rs @@ -4,13 +4,14 @@ //! Translation skeleton that traverses the whole WebAssembly module and call helper functions //! to deal with each part of it. use super::environ::ModuleEnvironment; +use super::error::from_binaryreadererror_wasmerror; use super::sections::{ parse_data_section, parse_element_section, parse_export_section, parse_function_section, parse_global_section, parse_import_section, parse_memory_section, parse_name_section, parse_start_section, parse_table_section, parse_type_section, }; use super::state::ModuleTranslationState; -use crate::WasmResult; +use wasmer_types::WasmResult; use wasmparser::{NameSectionReader, Parser, Payload}; /// Translate a sequence of bytes forming a valid Wasm binary into a @@ -22,7 +23,7 @@ pub fn translate_module<'data>( let mut module_translation_state = ModuleTranslationState::new(); for payload in Parser::new(0).parse_all(data) { - match payload? { + match payload.map_err(from_binaryreadererror_wasmerror)? { Payload::Version { .. } | Payload::End => {} Payload::TypeSection(types) => { @@ -68,7 +69,8 @@ pub fn translate_module<'data>( let offset = code.original_position(); environ.define_function_body( &module_translation_state, - code.read_bytes(size)?, + code.read_bytes(size) + .map_err(from_binaryreadererror_wasmerror)?, offset, )?; } @@ -97,7 +99,11 @@ pub fn translate_module<'data>( data, data_offset, .. - } => parse_name_section(NameSectionReader::new(data, data_offset)?, environ)?, + } => parse_name_section( + NameSectionReader::new(data, data_offset) + .map_err(from_binaryreadererror_wasmerror)?, + environ, + )?, Payload::CustomSection { name, data, .. } => environ.custom_section(name, data)?, diff --git a/lib/compiler/src/translator/sections.rs b/lib/compiler/src/translator/sections.rs index f8ecaf29cf4..451360ba836 100644 --- a/lib/compiler/src/translator/sections.rs +++ b/lib/compiler/src/translator/sections.rs @@ -11,9 +11,9 @@ //! is handled, according to the semantics of WebAssembly, to only specific expressions that are //! interpreted on the fly. use super::environ::ModuleEnvironment; +use super::error::from_binaryreadererror_wasmerror; use super::state::ModuleTranslationState; use crate::wasm_unsupported; -use crate::{WasmError, WasmResult}; use core::convert::TryFrom; use std::boxed::Box; use std::collections::HashMap; @@ -24,6 +24,7 @@ use wasmer_types::{ DataIndex, ElemIndex, FunctionIndex, FunctionType, GlobalIndex, GlobalInit, GlobalType, MemoryIndex, MemoryType, Pages, SignatureIndex, TableIndex, TableType, Type, V128, }; +use wasmer_types::{WasmError, WasmResult}; use wasmparser::{ self, Data, DataKind, DataSectionReader, Element, ElementItem, ElementItems, ElementKind, ElementSectionReader, Export, ExportSectionReader, ExternalKind, FuncType as WPFunctionType, @@ -93,7 +94,7 @@ pub fn parse_import_section<'data>( environ.reserve_imports(imports.get_count())?; for entry in imports { - let import = entry?; + let import = entry.map_err(from_binaryreadererror_wasmerror)?; let module_name = import.module; let field_name = import.field; @@ -172,7 +173,7 @@ pub fn parse_function_section( environ.reserve_func_types(num_functions)?; for entry in functions { - let sigindex = entry?; + let sigindex = entry.map_err(from_binaryreadererror_wasmerror)?; environ.declare_func_type(SignatureIndex::from_u32(sigindex))?; } @@ -187,7 +188,7 @@ pub fn parse_table_section( environ.reserve_tables(tables.get_count())?; for entry in tables { - let table = entry?; + let table = entry.map_err(from_binaryreadererror_wasmerror)?; environ.declare_table(TableType { ty: wptype_to_type(table.element_type).unwrap(), minimum: table.initial, @@ -211,7 +212,7 @@ pub fn parse_memory_section( memory64, initial, maximum, - } = entry?; + } = entry.map_err(from_binaryreadererror_wasmerror)?; if memory64 { unimplemented!("64bit memory not implemented yet"); } @@ -239,9 +240,12 @@ pub fn parse_global_section( mutable, }, init_expr, - } = entry?; + } = entry.map_err(from_binaryreadererror_wasmerror)?; let mut init_expr_reader = init_expr.get_binary_reader(); - let initializer = match init_expr_reader.read_operator()? { + let initializer = match init_expr_reader + .read_operator() + .map_err(from_binaryreadererror_wasmerror)? + { Operator::I32Const { value } => GlobalInit::I32Const(value), Operator::I64Const { value } => GlobalInit::I64Const(value), Operator::F32Const { value } => GlobalInit::F32Const(f32::from_bits(value.bits())), @@ -283,7 +287,7 @@ pub fn parse_export_section<'data>( field, ref kind, index, - } = entry?; + } = entry.map_err(from_binaryreadererror_wasmerror)?; // The input has already been validated, so we should be able to // assume valid UTF-8 and use `from_utf8_unchecked` if performance @@ -320,11 +324,17 @@ pub fn parse_start_section(index: u32, environ: &mut ModuleEnvironment) -> WasmR } fn read_elems(items: &ElementItems) -> WasmResult> { - let items_reader = items.get_items_reader()?; + let items_reader = items + .get_items_reader() + .map_err(from_binaryreadererror_wasmerror)?; let mut elems = Vec::with_capacity(usize::try_from(items_reader.get_count()).unwrap()); for item in items_reader { - let elem = match item? { - ElementItem::Expr(init) => match init.get_binary_reader().read_operator()? { + let elem = match item.map_err(from_binaryreadererror_wasmerror)? { + ElementItem::Expr(init) => match init + .get_binary_reader() + .read_operator() + .map_err(from_binaryreadererror_wasmerror)? + { Operator::RefNull { .. } => FunctionIndex::reserved_value(), Operator::RefFunc { function_index } => FunctionIndex::from_u32(function_index), s => { @@ -354,7 +364,7 @@ pub fn parse_element_section<'data>( items, ty, range: _, - } = entry?; + } = entry.map_err(from_binaryreadererror_wasmerror)?; if ty != wasmparser::Type::FuncRef { return Err(wasm_unsupported!( "unsupported table element type: {:?}", @@ -368,7 +378,10 @@ pub fn parse_element_section<'data>( init_expr, } => { let mut init_expr_reader = init_expr.get_binary_reader(); - let (base, offset) = match init_expr_reader.read_operator()? { + let (base, offset) = match init_expr_reader + .read_operator() + .map_err(from_binaryreadererror_wasmerror)? + { Operator::I32Const { value } => (None, value as u32 as usize), Operator::GlobalGet { global_index } => { (Some(GlobalIndex::from_u32(global_index)), 0) @@ -409,14 +422,17 @@ pub fn parse_data_section<'data>( kind, data, range: _, - } = entry?; + } = entry.map_err(from_binaryreadererror_wasmerror)?; match kind { DataKind::Active { memory_index, init_expr, } => { let mut init_expr_reader = init_expr.get_binary_reader(); - let (base, offset) = match init_expr_reader.read_operator()? { + let (base, offset) = match init_expr_reader + .read_operator() + .map_err(from_binaryreadererror_wasmerror)? + { Operator::I32Const { value } => (None, value as u32 as usize), Operator::GlobalGet { global_index } => { (Some(GlobalIndex::from_u32(global_index)), 0) diff --git a/lib/compiler/src/translator/state.rs b/lib/compiler/src/translator/state.rs index 2d72168cbbb..cb839eeffd1 100644 --- a/lib/compiler/src/translator/state.rs +++ b/lib/compiler/src/translator/state.rs @@ -1,10 +1,10 @@ // This file contains code from external sources. // Attributions: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md -use crate::{wasm_unsupported, WasmResult}; +use crate::wasm_unsupported; use std::boxed::Box; use wasmer_types::entity::PrimaryMap; -use wasmer_types::SignatureIndex; +use wasmer_types::{SignatureIndex, WasmResult}; /// Map of signatures to a function's parameter and return types. pub(crate) type WasmTypes = diff --git a/lib/universal-artifact/src/artifact.rs b/lib/compiler/src/universal_artifact/artifact.rs similarity index 90% rename from lib/universal-artifact/src/artifact.rs rename to lib/compiler/src/universal_artifact/artifact.rs index 5ceb2fd7bb2..08ebe14c121 100644 --- a/lib/universal-artifact/src/artifact.rs +++ b/lib/compiler/src/universal_artifact/artifact.rs @@ -1,25 +1,29 @@ //! Define `UniversalArtifactBuild` to allow compiling and instantiating to be //! done as separate steps. -use crate::serialize::SerializableCompilation; -use crate::serialize::SerializableModule; -#[cfg(feature = "compiler")] -use crate::trampoline::{libcall_trampoline_len, make_libcall_trampolines}; +#[cfg(feature = "universal_engine")] +use super::serialize::SerializableCompilation; +use super::serialize::SerializableModule; +#[cfg(feature = "universal_engine")] +use super::trampoline::{libcall_trampoline_len, make_libcall_trampolines}; +use crate::MetadataHeader; use crate::{ArtifactCreate, UniversalEngineBuilder}; +use crate::{CpuFeature, Features, Triple}; +#[cfg(feature = "universal_engine")] +use crate::{ModuleEnvironment, ModuleMiddlewareChain, Target}; use enumset::EnumSet; use std::mem; use std::sync::Arc; -use wasmer_artifact::{MetadataHeader, SerializeError}; -use wasmer_compiler::{ - CompileError, CompileModuleInfo, CompiledFunctionFrameInfo, CpuFeature, CustomSection, Dwarf, - Features, FunctionBody, ModuleEnvironment, ModuleMiddlewareChain, Relocation, SectionIndex, - Target, Triple, -}; use wasmer_types::entity::PrimaryMap; +#[cfg(feature = "universal_engine")] +use wasmer_types::CompileModuleInfo; +use wasmer_types::SerializeError; use wasmer_types::{ - FunctionIndex, LocalFunctionIndex, MemoryIndex, MemoryStyle, ModuleInfo, OwnedDataInitializer, - SignatureIndex, TableIndex, TableStyle, + CompileError, CustomSection, Dwarf, FunctionIndex, LocalFunctionIndex, MemoryIndex, + MemoryStyle, ModuleInfo, OwnedDataInitializer, Relocation, SectionIndex, SignatureIndex, + TableIndex, TableStyle, }; +use wasmer_types::{CompiledFunctionFrameInfo, FunctionBody}; /// A compiled wasm module, ready to be instantiated. pub struct UniversalArtifactBuild { @@ -36,7 +40,7 @@ impl UniversalArtifactBuild { } /// Compile a data buffer into a `UniversalArtifactBuild`, which may then be instantiated. - #[cfg(feature = "compiler")] + #[cfg(feature = "universal_engine")] pub fn new( inner_engine: &mut UniversalEngineBuilder, data: &[u8], @@ -115,7 +119,7 @@ impl UniversalArtifactBuild { } /// Compile a data buffer into a `UniversalArtifactBuild`, which may then be instantiated. - #[cfg(not(feature = "compiler"))] + #[cfg(not(feature = "universal_engine"))] pub fn new(_engine: &UniversalEngineBuilder, _data: &[u8]) -> Result { Err(CompileError::Codegen( "Compilation is not enabled in the engine".to_string(), diff --git a/lib/universal-artifact/src/engine.rs b/lib/compiler/src/universal_artifact/engine.rs similarity index 55% rename from lib/universal-artifact/src/engine.rs rename to lib/compiler/src/universal_artifact/engine.rs index 573e8762621..34c96573186 100644 --- a/lib/universal-artifact/src/engine.rs +++ b/lib/compiler/src/universal_artifact/engine.rs @@ -1,13 +1,11 @@ //! Universal compilation. -use wasmer_compiler::CompileError; -use wasmer_compiler::Compiler; -use wasmer_types::Features; +use crate::Compiler; +use wasmer_types::{CompileError, Features}; /// The Builder contents of `UniversalEngine` pub struct UniversalEngineBuilder { /// The compiler - #[cfg(feature = "compiler")] compiler: Option>, /// The features to compile the Wasm module with features: Features, @@ -15,13 +13,11 @@ pub struct UniversalEngineBuilder { impl UniversalEngineBuilder { /// Create a new builder with pre-made components - #[cfg(feature = "compiler")] pub fn new(compiler: Option>, features: Features) -> Self { Self { compiler, features } } /// Gets the compiler associated to this engine. - #[cfg(feature = "compiler")] pub fn compiler(&self) -> Result<&dyn Compiler, CompileError> { if self.compiler.is_none() { return Err(CompileError::Codegen( @@ -31,29 +27,11 @@ impl UniversalEngineBuilder { Ok(&**self.compiler.as_ref().unwrap()) } - /// Gets the compiler associated to this engine. - #[cfg(not(feature = "compiler"))] - pub fn compiler(&self) -> Result<&dyn Compiler, CompileError> { - return Err(CompileError::Codegen( - "The UniversalEngine is not compiled in.".to_string(), - )); - } - /// Validate the module - #[cfg(feature = "compiler")] pub fn validate(&self, data: &[u8]) -> Result<(), CompileError> { self.compiler()?.validate_module(self.features(), data) } - /// Validate the module - #[cfg(not(feature = "compiler"))] - pub fn validate<'data>(&self, _data: &'data [u8]) -> Result<(), CompileError> { - Err(CompileError::Validate( - "The UniversalEngine is not compiled with compiler support, which is required for validating" - .to_string(), - )) - } - /// The Wasm features pub fn features(&self) -> &Features { &self.features diff --git a/lib/compiler/src/universal_artifact/mod.rs b/lib/compiler/src/universal_artifact/mod.rs new file mode 100644 index 00000000000..3a081e84467 --- /dev/null +++ b/lib/compiler/src/universal_artifact/mod.rs @@ -0,0 +1,11 @@ +//! Generic Artifact abstraction for Wasmer Engines. + +mod artifact; +mod engine; +mod serialize; +mod trampoline; + +pub use self::artifact::UniversalArtifactBuild; +pub use self::engine::UniversalEngineBuilder; +pub use self::serialize::SerializableModule; +pub use self::trampoline::*; diff --git a/lib/universal-artifact/src/serialize.rs b/lib/compiler/src/universal_artifact/serialize.rs similarity index 95% rename from lib/universal-artifact/src/serialize.rs rename to lib/compiler/src/universal_artifact/serialize.rs index 8bfc40db69b..e7d425115db 100644 --- a/lib/universal-artifact/src/serialize.rs +++ b/lib/compiler/src/universal_artifact/serialize.rs @@ -3,12 +3,10 @@ use rkyv::{ ser::Serializer as RkyvSerializer, Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize, }; -use wasmer_artifact::{DeserializeError, SerializeError}; -use wasmer_compiler::{ - CompileModuleInfo, CompiledFunctionFrameInfo, CustomSection, Dwarf, FunctionBody, Relocation, - SectionIndex, -}; use wasmer_types::entity::PrimaryMap; +use wasmer_types::{CompileModuleInfo, CompiledFunctionFrameInfo, Dwarf, FunctionBody}; +use wasmer_types::{CustomSection, Relocation, SectionIndex}; +use wasmer_types::{DeserializeError, SerializeError}; use wasmer_types::{FunctionIndex, LocalFunctionIndex, OwnedDataInitializer, SignatureIndex}; /// The compilation related data for a serialized modules diff --git a/lib/universal-artifact/src/trampoline.rs b/lib/compiler/src/universal_artifact/trampoline.rs similarity index 94% rename from lib/universal-artifact/src/trampoline.rs rename to lib/compiler/src/universal_artifact/trampoline.rs index 65932be48ae..135827072b0 100644 --- a/lib/universal-artifact/src/trampoline.rs +++ b/lib/compiler/src/universal_artifact/trampoline.rs @@ -3,12 +3,12 @@ //! This is needed because the target of libcall relocations are not reachable //! through normal branch instructions. +use crate::{Architecture, Target}; use enum_iterator::IntoEnumIterator; -use wasmer_compiler::{ - Architecture, CustomSection, CustomSectionProtection, Relocation, RelocationKind, - RelocationTarget, SectionBody, Target, +use wasmer_types::{ + CustomSection, CustomSectionProtection, LibCall, Relocation, RelocationKind, RelocationTarget, + SectionBody, }; -use wasmer_types::LibCall; // SystemV says that both x16 and x17 are available as intra-procedural scratch // registers but Apple's ABI restricts us to use x17. diff --git a/lib/engine-dylib/Cargo.toml b/lib/engine-dylib/Cargo.toml deleted file mode 100644 index 325a7d61083..00000000000 --- a/lib/engine-dylib/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "wasmer-engine-dylib" -version = "2.3.0" -description = "Wasmer Dylib Engine" -categories = ["wasm"] -keywords = ["wasm", "webassembly", "engine", "dylib"] -authors = ["Wasmer Engineering Team "] -repository = "https://github.com/wasmerio/wasmer" -license = "MIT" -readme = "README.md" -edition = "2018" - -[dependencies] -wasmer-artifact = { path = "../artifact", version = "=2.3.0" } -wasmer-types = { path = "../types", version = "=2.3.0" } -wasmer-compiler = { path = "../compiler", version = "=2.3.0" } -wasmer-vm = { path = "../vm", version = "=2.3.0", features = ["enable-rkyv"] } -wasmer-engine = { path = "../engine", version = "=2.3.0" } -wasmer-object = { path = "../object", version = "=2.3.0" } -serde = { version = "1.0", features = ["derive", "rc"] } -cfg-if = "1.0" -tracing = { version = "0.1", features = ["log"] } -leb128 = "0.2" -libloading = "0.7" -tempfile = "3.1" -which = "4.0" -rkyv = "0.7.20" -enumset = "1.0" -enum-iterator = "0.7.0" -object = { version = "0.28.3", default-features = false, features = ["write"] } - -[features] -# Enable the `compiler` feature if you want the engine to compile -# and not be only on headless mode. -compiler = ["wasmer-compiler/translator"] - -[badges] -maintenance = { status = "actively-developed" } diff --git a/lib/engine-dylib/README.md b/lib/engine-dylib/README.md deleted file mode 100644 index 90987642a78..00000000000 --- a/lib/engine-dylib/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# `wasmer-engine-dylib` [![Build Status](https://github.com/wasmerio/wasmer/workflows/build/badge.svg?style=flat-square)](https://github.com/wasmerio/wasmer/actions?query=workflow%3Abuild) [![Join Wasmer Slack](https://img.shields.io/static/v1?label=Slack&message=join%20chat&color=brighgreen&style=flat-square)](https://slack.wasmer.io) [![MIT License](https://img.shields.io/github/license/wasmerio/wasmer.svg?style=flat-square)](https://github.com/wasmerio/wasmer/blob/master/LICENSE) - -The Wasmer Dylib engine is usable with any compiler implementation -based on [`wasmer-compiler`] that is able to emit -[Position-Independent Code][PIC] (PIC). - -After the compiler generates the machine code for the functions, the -Dylib Engine generates a shared object file and links it via [`dlsym`] -so it can be usable by the [`wasmer`] API. - -This allows Wasmer to achieve *blazing fast* **native startup times**. - -*Note: you can find a [full working example using the Dylib engine -here][example].* - -### Difference with `wasmer-engine-universal` - -The Dylib Engine and Universal Engine mainly differ on how the Modules -are loaded/stored. Using the same compilers, both will have the same -runtime speed. - -However, the Dylib Engine uses the Operating System shared library -loader (via `dlopen`) and as such is able to achieve a much faster -startup time when deserializing a serialized `Module`. - -## Requirements - -The `wasmer-engine-dylib` crate requires a linker available on -your system to generate the shared object file. - -We recommend having [`gcc`] or [`clang`] installed. - -> Note: when **cross-compiling** to other targets, `clang` will be the -> default command used for compiling. - -You can install LLVM (that provides `clang`) easily on your -Debian-like system via this command: - -```bash -bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" -``` - -Or in macOS: - -```bash -brew install llvm -``` - -Or via any of the [pre-built binaries that LLVM -offers][llvm-pre-built]. - - -[`wasmer-compiler`]: https://github.com/wasmerio/wasmer/tree/master/lib/compiler -[PIC]: https://en.wikipedia.org/wiki/Position-independent_code -[`dlsym`]: https://www.freebsd.org/cgi/man.cgi?query=dlsym -[`wasmer`]: https://github.com/wasmerio/wasmer/tree/master/lib/api -[example]: https://github.com/wasmerio/wasmer/blob/master/examples/engine_dylib.rs -[`gcc`]: https://gcc.gnu.org/ -[`clang`]: https://clang.llvm.org/ -[llvm-pre-built]: https://releases.llvm.org/download.html diff --git a/lib/engine-dylib/src/artifact.rs b/lib/engine-dylib/src/artifact.rs deleted file mode 100644 index a531d126c70..00000000000 --- a/lib/engine-dylib/src/artifact.rs +++ /dev/null @@ -1,897 +0,0 @@ -//! Define `DylibArtifact` to allow compiling and instantiating -//! to be done as separate steps. - -use crate::engine::{DylibEngine, DylibEngineInner}; -use crate::serialize::ModuleMetadata; -use crate::trampoline::{emit_trampolines, fill_trampoline_table, WASMER_TRAMPOLINES_SYMBOL}; -use enumset::EnumSet; -use libloading::{Library, Symbol as LibrarySymbol}; -use object::{write::CoffExportStyle, BinaryFormat}; -use std::error::Error; -use std::fs::{self, File}; -use std::io::{Read, Write}; -use std::path::{Path, PathBuf}; -#[cfg(feature = "compiler")] -use std::process::Command; -use std::sync::{Arc, Mutex}; -use tempfile::NamedTempFile; -use tracing::log::error; -#[cfg(feature = "compiler")] -use tracing::trace; -use wasmer_artifact::ArtifactCreate; -use wasmer_compiler::{ - Architecture, CompileError, CompiledFunctionFrameInfo, CpuFeature, Features, - FunctionAddressMap, OperatingSystem, Symbol, SymbolRegistry, Triple, -}; -#[cfg(feature = "compiler")] -use wasmer_compiler::{ - CompileModuleInfo, Compiler, FunctionBodyData, ModuleEnvironment, ModuleMiddlewareChain, - ModuleTranslationState, -}; -use wasmer_engine::{ - register_frame_info, Artifact, DeserializeError, FunctionExtent, GlobalFrameInfoRegistration, - InstantiationError, MetadataHeader, SerializeError, -}; -#[cfg(feature = "compiler")] -use wasmer_engine::{Engine, Tunables}; -#[cfg(feature = "compiler")] -use wasmer_object::{emit_compilation, emit_data, get_object_for_target}; -use wasmer_types::entity::{BoxedSlice, PrimaryMap}; -#[cfg(feature = "compiler")] -use wasmer_types::DataInitializer; -use wasmer_types::{ - FunctionIndex, LocalFunctionIndex, MemoryIndex, ModuleInfo, OwnedDataInitializer, - SignatureIndex, TableIndex, -}; -use wasmer_vm::{ - FuncDataRegistry, FunctionBodyPtr, MemoryStyle, TableStyle, VMFunctionBody, - VMSharedSignatureIndex, VMTrampoline, -}; - -/// A compiled Wasm module, ready to be instantiated. -pub struct DylibArtifact { - dylib_path: PathBuf, - is_temporary: bool, - metadata: ModuleMetadata, - finished_functions: BoxedSlice, - finished_function_call_trampolines: BoxedSlice, - finished_dynamic_function_trampolines: BoxedSlice, - func_data_registry: Arc, - signatures: BoxedSlice, - frame_info_registration: Mutex>, -} - -impl Drop for DylibArtifact { - fn drop(&mut self) { - if self.is_temporary { - if let Err(err) = std::fs::remove_file(&self.dylib_path) { - error!("cannot delete the temporary dylib artifact: {}", err); - } - } - } -} - -fn to_compile_error(err: impl Error) -> CompileError { - CompileError::Codegen(err.to_string()) -} - -const WASMER_METADATA_SYMBOL: &[u8] = b"WASMER_METADATA"; - -impl DylibArtifact { - // Mach-O header in iOS/Mac - #[allow(dead_code)] - const MAGIC_HEADER_MH_CIGAM_64: &'static [u8] = &[207, 250, 237, 254]; - - // ELF Magic header for Linux (32 bit) - #[allow(dead_code)] - const MAGIC_HEADER_ELF_32: &'static [u8] = &[0x7f, b'E', b'L', b'F', 1]; - - // ELF Magic header for Linux (64 bit) - #[allow(dead_code)] - const MAGIC_HEADER_ELF_64: &'static [u8] = &[0x7f, b'E', b'L', b'F', 2]; - - // COFF Magic header for Windows (64 bit) - #[allow(dead_code)] - const MAGIC_HEADER_COFF_64: &'static [u8] = &[b'M', b'Z']; - - /// Check if the provided bytes look like `DylibArtifact`. - /// - /// This means, if the bytes look like a shared object file in the target - /// system. - pub fn is_deserializable(bytes: &[u8]) -> bool { - cfg_if::cfg_if! { - if #[cfg(all(target_pointer_width = "64", target_vendor="apple"))] { - bytes.starts_with(Self::MAGIC_HEADER_MH_CIGAM_64) - } - else if #[cfg(all(target_pointer_width = "64", target_os="linux"))] { - bytes.starts_with(Self::MAGIC_HEADER_ELF_64) - } - else if #[cfg(all(target_pointer_width = "32", target_os="linux"))] { - bytes.starts_with(Self::MAGIC_HEADER_ELF_32) - } - else if #[cfg(all(target_pointer_width = "64", target_os="windows"))] { - bytes.starts_with(Self::MAGIC_HEADER_COFF_64) - } - else { - false - } - } - } - - /// Generate a compilation - #[cfg(feature = "compiler")] - #[allow(clippy::type_complexity)] - fn generate_metadata<'data>( - data: &'data [u8], - features: &Features, - compiler: &dyn Compiler, - tunables: &dyn Tunables, - ) -> Result< - ( - CompileModuleInfo, - PrimaryMap>, - Vec>, - Option, - ), - CompileError, - > { - let environ = ModuleEnvironment::new(); - let translation = environ.translate(data).map_err(CompileError::Wasm)?; - - // We try to apply the middleware first - let mut module = translation.module; - let middlewares = compiler.get_middlewares(); - middlewares.apply_on_module_info(&mut module); - - let memory_styles: PrimaryMap = module - .memories - .values() - .map(|memory_type| tunables.memory_style(memory_type)) - .collect(); - let table_styles: PrimaryMap = module - .tables - .values() - .map(|table_type| tunables.table_style(table_type)) - .collect(); - - let compile_info = CompileModuleInfo { - module: Arc::new(module), - features: features.clone(), - memory_styles, - table_styles, - }; - Ok(( - compile_info, - translation.function_body_inputs, - translation.data_initializers, - translation.module_translation_state, - )) - } - - /// Compile a data buffer into a `DylibArtifact`, which may - /// then be instantiated. - #[cfg(feature = "compiler")] - pub fn new( - engine: &DylibEngine, - data: &[u8], - tunables: &dyn Tunables, - ) -> Result { - let mut engine_inner = engine.inner_mut(); - let target = engine.target(); - let compiler = engine_inner.compiler()?; - let (compile_info, function_body_inputs, data_initializers, module_translation) = - Self::generate_metadata(data, engine_inner.features(), compiler, tunables)?; - - let data_initializers = data_initializers - .iter() - .map(OwnedDataInitializer::new) - .collect::>() - .into_boxed_slice(); - - let target_triple = target.triple(); - - /* - // We construct the function body lengths - let function_body_lengths = compilation - .get_function_bodies() - .values() - .map(|function_body| function_body.body.len() as u64) - .map(|_function_body| 0u64) - .collect::>(); - */ - - // TODO: we currently supply all-zero function body lengths. - // We don't know the lengths until they're compiled, yet we have to - // supply the metadata as an input to the compile. - let function_body_lengths = function_body_inputs - .keys() - .map(|_function_body| 0u64) - .collect::>(); - - let function_frame_info = None; - - let mut metadata = ModuleMetadata { - compile_info, - function_frame_info, - prefix: engine_inner.get_prefix(data), - data_initializers, - function_body_lengths, - cpu_features: target.cpu_features().as_u64(), - }; - - let serialized_data = metadata.serialize()?; - - let mut metadata_binary = vec![]; - metadata_binary.extend(MetadataHeader::new(serialized_data.len()).into_bytes()); - metadata_binary.extend(serialized_data); - - let (compile_info, symbol_registry) = metadata.split(); - - let maybe_obj_bytes = compiler.experimental_native_compile_module( - target, - compile_info, - module_translation.as_ref().unwrap(), - &function_body_inputs, - &symbol_registry, - &metadata_binary, - ); - - let mut extra_filepath = None; - let filepath = match maybe_obj_bytes { - Some(obj_bytes) => { - extra_filepath = { - // Create a separate object file with the trampolines. - let mut obj = get_object_for_target(target_triple).map_err(to_compile_error)?; - emit_trampolines(&mut obj, engine.target()); - if obj.format() == BinaryFormat::Coff { - obj.add_coff_exports(CoffExportStyle::Gnu); - } - let file = tempfile::Builder::new() - .prefix("wasmer_dylib_") - .suffix(".o") - .tempfile() - .map_err(to_compile_error)?; - - // Re-open it. - let (mut file, filepath) = file.keep().map_err(to_compile_error)?; - let obj_bytes = obj.write().map_err(to_compile_error)?; - file.write_all(&obj_bytes).map_err(to_compile_error)?; - Some(filepath) - }; - - // Write the object file generated by the compiler. - let obj_bytes = obj_bytes?; - let file = tempfile::Builder::new() - .prefix("wasmer_dylib_") - .suffix(".o") - .tempfile() - .map_err(to_compile_error)?; - - // Re-open it. - let (mut file, filepath) = file.keep().map_err(to_compile_error)?; - file.write_all(&obj_bytes).map_err(to_compile_error)?; - filepath - } - None => { - let compilation = compiler.compile_module( - target, - compile_info, - module_translation.as_ref().unwrap(), - function_body_inputs, - )?; - let mut obj = get_object_for_target(target_triple).map_err(to_compile_error)?; - emit_trampolines(&mut obj, engine.target()); - emit_data( - &mut obj, - WASMER_METADATA_SYMBOL, - &metadata_binary, - MetadataHeader::ALIGN as u64, - ) - .map_err(to_compile_error)?; - - let frame_info = compilation.get_frame_info(); - - emit_compilation(&mut obj, compilation, &symbol_registry, target_triple) - .map_err(to_compile_error)?; - if obj.format() == BinaryFormat::Coff { - obj.add_coff_exports(CoffExportStyle::Gnu); - } - let file = tempfile::Builder::new() - .prefix("wasmer_dylib_") - .suffix(".o") - .tempfile() - .map_err(to_compile_error)?; - - metadata.function_frame_info = Some(frame_info); - - // Re-open it. - let (mut file, filepath) = file.keep().map_err(to_compile_error)?; - let obj_bytes = obj.write().map_err(to_compile_error)?; - - file.write_all(&obj_bytes).map_err(to_compile_error)?; - filepath - } - }; - - let output_filepath = { - let suffix = format!(".{}", Self::get_default_extension(target_triple)); - let shared_file = tempfile::Builder::new() - .prefix("wasmer_dylib_") - .suffix(&suffix) - .tempfile() - .map_err(to_compile_error)?; - shared_file - .into_temp_path() - .keep() - .map_err(to_compile_error)? - }; - - let is_cross_compiling = engine_inner.is_cross_compiling(); - let target_triple_str = { - let into_str = target_triple.to_string(); - // We have to adapt the target triple string, because otherwise - // Apple's clang will not recognize it. - if into_str == "aarch64-apple-darwin" { - "arm64-apple-darwin".to_string() - } else { - into_str - } - }; - - // Set 'isysroot' clang flag if compiling to iOS target - let ios_compile_target = target_triple.operating_system == OperatingSystem::Ios; - let ios_sdk_flag = { - if ios_compile_target { - if target_triple.architecture == Architecture::X86_64 { - "-isysroot/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk" - } else { - "-isysroot/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk" - } - } else { - "" - } - }; - let ios_sdk_lib = { - if ios_compile_target { - "-lSystem" - } else { - "" - } - }; - - // Get the location of the 'ld' linker for clang - let fuse_linker = { - let ld_install = which::which("ld"); - match (ios_compile_target, ld_install) { - (true, Ok(ld_install)) => ld_install.into_os_string().into_string().unwrap(), - _ => "lld".to_string(), - } - }; - - let cross_compiling_args: Vec = if is_cross_compiling { - vec![ - format!("--target={}", target_triple_str), - format!("-fuse-ld={}", fuse_linker), - "-nodefaultlibs".to_string(), - "-nostdlib".to_string(), - ios_sdk_flag.to_string(), - ios_sdk_lib.to_string(), - ] - } else { - // We are explicit on the target when the host system is - // Apple Silicon, otherwise compilation fails. - if target_triple_str == "arm64-apple-darwin" { - vec![format!("--target={}", target_triple_str)] - } else { - vec![] - } - }; - let target_args = match (target_triple.operating_system, is_cross_compiling) { - (OperatingSystem::Windows, true) => vec!["-Wl,/force:unresolved,/noentry"], - (OperatingSystem::Windows, false) => vec!["-Wl,-undefined,dynamic_lookup"], - _ => vec!["-nostartfiles", "-Wl,-undefined,dynamic_lookup"], - }; - trace!( - "Compiling for target {} from host {}", - target_triple_str, - Triple::host().to_string(), - ); - - let linker = engine_inner.linker().executable(); - let output = Command::new(linker) - .arg(&filepath) - .args(&extra_filepath) - .arg("-o") - .arg(&output_filepath) - .args(&target_args) - // .args(&wasmer_symbols) - .arg("-shared") - .args(&cross_compiling_args) - .arg("-v") - .output() - .map_err(to_compile_error); - - if fs::metadata(&filepath).is_ok() { - fs::remove_file(filepath).map_err(to_compile_error)?; - } - if let Some(filepath) = extra_filepath { - if fs::metadata(&filepath).is_ok() { - fs::remove_file(filepath).map_err(to_compile_error)?; - } - } - - let output = output?; - - if !output.status.success() { - return Err(CompileError::Codegen(format!( - "Shared object file generator failed with:\nstderr:{}\nstdout:{}", - String::from_utf8_lossy(&output.stderr).trim_end(), - String::from_utf8_lossy(&output.stdout).trim_end() - ))); - } - - trace!("gcc command result {:?}", output); - - let mut artifact = if is_cross_compiling { - Self::from_parts_crosscompiled(metadata, output_filepath) - } else { - let lib = unsafe { Library::new(&output_filepath).map_err(to_compile_error)? }; - Self::from_parts(&mut engine_inner, metadata, output_filepath, lib) - }?; - artifact.is_temporary = true; - - Ok(artifact) - } - - /// Get the default extension when serializing this artifact - pub fn get_default_extension(triple: &Triple) -> &'static str { - match triple.operating_system { - OperatingSystem::Windows => "dll", - OperatingSystem::Darwin | OperatingSystem::Ios | OperatingSystem::MacOSX { .. } => { - "dylib" - } - _ => "so", - } - } - - /// Construct a `DylibArtifact` from component parts. - pub fn from_parts_crosscompiled( - metadata: ModuleMetadata, - dylib_path: PathBuf, - ) -> Result { - let finished_functions: PrimaryMap = PrimaryMap::new(); - let finished_function_call_trampolines: PrimaryMap = - PrimaryMap::new(); - let finished_dynamic_function_trampolines: PrimaryMap = - PrimaryMap::new(); - let signatures: PrimaryMap = PrimaryMap::new(); - Ok(Self { - dylib_path, - is_temporary: false, - metadata, - finished_functions: finished_functions.into_boxed_slice(), - finished_function_call_trampolines: finished_function_call_trampolines - .into_boxed_slice(), - finished_dynamic_function_trampolines: finished_dynamic_function_trampolines - .into_boxed_slice(), - func_data_registry: Arc::new(FuncDataRegistry::new()), - signatures: signatures.into_boxed_slice(), - frame_info_registration: Mutex::new(None), - }) - } - - /// Construct a `DylibArtifact` from component parts. - pub fn from_parts( - engine_inner: &mut DylibEngineInner, - metadata: ModuleMetadata, - dylib_path: PathBuf, - lib: Library, - ) -> Result { - unsafe { - let trampolines_symbol: LibrarySymbol = lib - .get(WASMER_TRAMPOLINES_SYMBOL) - .expect("missing WASMER_TRAMPOLINES symbol"); - fill_trampoline_table(trampolines_symbol.into_raw().into_raw() as *mut usize); - } - - let mut finished_functions: PrimaryMap = - PrimaryMap::new(); - for (function_local_index, _function_len) in metadata.function_body_lengths.iter() { - let function_name = metadata - .get_symbol_registry() - .symbol_to_name(Symbol::LocalFunction(function_local_index)); - unsafe { - // We use a fake function signature `fn()` because we just - // want to get the function address. - let func: LibrarySymbol = lib - .get(function_name.as_bytes()) - .map_err(to_compile_error)?; - finished_functions.push(FunctionBodyPtr( - func.into_raw().into_raw() as *const VMFunctionBody - )); - } - } - - // Retrieve function call trampolines - let mut finished_function_call_trampolines: PrimaryMap = - PrimaryMap::with_capacity(metadata.compile_info.module.signatures.len()); - for sig_index in metadata.compile_info.module.signatures.keys() { - let function_name = metadata - .get_symbol_registry() - .symbol_to_name(Symbol::FunctionCallTrampoline(sig_index)); - unsafe { - let trampoline: LibrarySymbol = lib - .get(function_name.as_bytes()) - .map_err(to_compile_error)?; - let raw = *trampoline.into_raw(); - finished_function_call_trampolines.push(raw); - } - } - - // Retrieve dynamic function trampolines (only for imported functions) - let mut finished_dynamic_function_trampolines: PrimaryMap = - PrimaryMap::with_capacity(metadata.compile_info.module.num_imported_functions); - for func_index in metadata - .compile_info - .module - .functions - .keys() - .take(metadata.compile_info.module.num_imported_functions) - { - let function_name = metadata - .get_symbol_registry() - .symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index)); - unsafe { - let trampoline: LibrarySymbol = lib - .get(function_name.as_bytes()) - .map_err(to_compile_error)?; - finished_dynamic_function_trampolines.push(FunctionBodyPtr( - trampoline.into_raw().into_raw() as *const VMFunctionBody, - )); - } - } - - // Compute indices into the shared signature table. - let signatures = { - metadata - .compile_info - .module - .signatures - .values() - .map(|sig| engine_inner.signatures().register(sig)) - .collect::>() - }; - - engine_inner.add_library(lib); - - Ok(Self { - dylib_path, - is_temporary: false, - metadata, - finished_functions: finished_functions.into_boxed_slice(), - finished_function_call_trampolines: finished_function_call_trampolines - .into_boxed_slice(), - finished_dynamic_function_trampolines: finished_dynamic_function_trampolines - .into_boxed_slice(), - func_data_registry: engine_inner.func_data().clone(), - signatures: signatures.into_boxed_slice(), - frame_info_registration: Mutex::new(None), - }) - } - - /// Compile a data buffer into a `DylibArtifact`, which may - /// then be instantiated. - #[cfg(not(feature = "compiler"))] - pub fn new(_engine: &DylibEngine, _data: &[u8]) -> Result { - Err(CompileError::Codegen( - "Compilation is not enabled in the engine".to_string(), - )) - } - - /// Deserialize a `DylibArtifact` from bytes. - /// - /// # Safety - /// - /// The bytes must represent a serialized WebAssembly module. - pub unsafe fn deserialize( - engine: &DylibEngine, - bytes: &[u8], - ) -> Result { - if !Self::is_deserializable(bytes) { - return Err(DeserializeError::Incompatible( - "The provided bytes are not in any native format Wasmer can understand".to_string(), - )); - } - // Dump the bytes into a file, so we can read it with our `dlopen` - let named_file = NamedTempFile::new()?; - let (mut file, path) = named_file.keep().map_err(|e| e.error)?; - file.write_all(bytes)?; - // We already checked for the header, so we don't need - // to check again. - let mut artifact = Self::deserialize_from_file_unchecked(engine, &path)?; - artifact.is_temporary = true; - - Ok(artifact) - } - - /// Deserialize a `DylibArtifact` from a file path. - /// - /// # Safety - /// - /// The file's content must represent a serialized WebAssembly module. - pub unsafe fn deserialize_from_file( - engine: &DylibEngine, - path: &Path, - ) -> Result { - let mut file = File::open(&path)?; - let mut buffer = [0; 5]; - // read up to 5 bytes - file.read_exact(&mut buffer)?; - if !Self::is_deserializable(&buffer) { - return Err(DeserializeError::Incompatible( - "The provided bytes are not in any native format Wasmer can understand".to_string(), - )); - } - Self::deserialize_from_file_unchecked(engine, path) - } - - /// Deserialize a `DylibArtifact` from a file path (unchecked). - /// - /// # Safety - /// - /// The file's content must represent a serialized WebAssembly module. - pub unsafe fn deserialize_from_file_unchecked( - engine: &DylibEngine, - path: &Path, - ) -> Result { - let lib = Library::new(&path).map_err(|e| { - DeserializeError::CorruptedBinary(format!("Library loading failed: {}", e)) - })?; - let shared_path: PathBuf = PathBuf::from(path); - let metadata_symbol: LibrarySymbol<*mut [u8; MetadataHeader::LEN]> = - lib.get(WASMER_METADATA_SYMBOL).map_err(|e| { - DeserializeError::CorruptedBinary(format!( - "The provided object file doesn't seem to be generated by Wasmer: {}", - e - )) - })?; - use std::slice; - - let metadata = &**metadata_symbol; - let metadata_len = MetadataHeader::parse(metadata)?; - let metadata_slice: &'static [u8] = - slice::from_raw_parts(metadata.as_ptr().add(MetadataHeader::LEN), metadata_len); - - let metadata = ModuleMetadata::deserialize(metadata_slice)?; - - let mut engine_inner = engine.inner_mut(); - - Self::from_parts(&mut engine_inner, metadata, shared_path, lib) - .map_err(DeserializeError::Compiler) - } - - /// Used in test deserialize metadata is correct - pub fn metadata(&self) -> &ModuleMetadata { - &self.metadata - } -} - -impl ArtifactCreate for DylibArtifact { - fn module(&self) -> Arc { - self.metadata.compile_info.module.clone() - } - - fn module_ref(&self) -> &ModuleInfo { - &self.metadata.compile_info.module - } - - fn module_mut(&mut self) -> Option<&mut ModuleInfo> { - Arc::get_mut(&mut self.metadata.compile_info.module) - } - - fn features(&self) -> &Features { - &self.metadata.compile_info.features - } - - fn cpu_features(&self) -> enumset::EnumSet { - EnumSet::from_u64(self.metadata.cpu_features) - } - - fn data_initializers(&self) -> &[OwnedDataInitializer] { - &*self.metadata.data_initializers - } - - fn memory_styles(&self) -> &PrimaryMap { - &self.metadata.compile_info.memory_styles - } - - fn table_styles(&self) -> &PrimaryMap { - &self.metadata.compile_info.table_styles - } - - /// Serialize a `DylibArtifact`. - fn serialize(&self) -> Result, SerializeError> { - Ok(std::fs::read(&self.dylib_path)?) - } - - /// Serialize a `DylibArtifact` to a portable file - #[cfg(feature = "compiler")] - fn serialize_to_file(&self, path: &Path) -> Result<(), SerializeError> { - let serialized = self.serialize()?; - std::fs::write(&path, serialized)?; - - /* - When you write the artifact to a new file it still has the 'Mach-O Identifier' - of the original file, and so this can causes linker issues when adding - the new file to an XCode project. - - The below code renames the ID of the file so that it references itself through - an @executable_path prefix. Basically it tells XCode to find this file - inside of the projects' list of 'linked executables'. - - You need to be running MacOS for the following to actually work though. - */ - let has_extension = path.extension().is_some(); - if has_extension && path.extension().unwrap() == "dylib" { - let filename = path.file_name().unwrap().to_str().unwrap(); - let parent_dir = path.parent().unwrap(); - let absolute_path = std::fs::canonicalize(&parent_dir) - .unwrap() - .into_os_string() - .into_string() - .unwrap(); - - Command::new("install_name_tool") - .arg("-id") - .arg(format!("@executable_path/{}", &filename)) - .arg(&filename) - .current_dir(&absolute_path) - .output()?; - } - - Ok(()) - } -} -impl Artifact for DylibArtifact { - fn register_frame_info(&self) { - let mut info = self.frame_info_registration.lock().unwrap(); - - if info.is_some() { - return; - } - - // We (reverse) order all the functions by their pointer location. - // [f9, f6, f7, f8...] and calculate their potential function body size by - // getting the diff in pointers between functions (since they are all located - // in the same __text section). - - let min_call_trampolines_pointer = self - .finished_function_call_trampolines - .values() - .map(|t| *t as usize) - .min() - .unwrap_or(0); - let min_dynamic_trampolines_pointer = self - .finished_dynamic_function_trampolines - .values() - .map(|t| **t as usize) - .min() - .unwrap_or(0); - - let fp = self.finished_functions.clone(); - let mut function_pointers = fp.into_iter().collect::>(); - - // Sort the keys by the funciton pointer values in reverse order. - // This way we can get the maximum function lengths (since functions can't overlap in memory) - function_pointers.sort_by(|(_k1, v1), (_k2, v2)| v2.cmp(v1)); - let mut iter = function_pointers.into_iter(); - let mut function_pointers = iter - .next() - .map(|(index, function_pointer)| { - let fp = **function_pointer as usize; - // In case we are in the first function pointer (the one with the highest pointer) - // we try to determine it's bounds (function size) by using the other function trampoline - // locations. - let current_size_by_ptr = if fp < min_call_trampolines_pointer { - if min_call_trampolines_pointer < min_dynamic_trampolines_pointer - || min_dynamic_trampolines_pointer == 0 - { - min_call_trampolines_pointer - fp - } else { - min_dynamic_trampolines_pointer - fp - } - } else if fp < min_dynamic_trampolines_pointer { - min_dynamic_trampolines_pointer - fp - } else { - // The trampoline pointers are before the function. - // We can safely assume the function will be at least 16 bits of length. - // This is a very hacky assumption, but it makes collisions work perfectly - // Since DLOpen simlinks will always be > 16 bits of difference between - // two different libraries for the same symbol. - // Note: the minmum Mach-O file is 0x1000 bytes and the minimum ELF is 0x0060 bytes - 16 - }; - let mut prev_pointer = fp; - // We choose the minimum between the function size given the pointer diff - // and the emitted size by the address map - let ptr = function_pointer; - let length = current_size_by_ptr; - let first = (index, FunctionExtent { ptr: *ptr, length }); - std::iter::once(first) - .chain(iter.map(|(index, function_pointer)| { - let fp = **function_pointer as usize; - // This assumes we never lay any functions bodies across the usize::MAX..nullptr - // wrapping point. - // Which is generally true on most OSes, but certainly doesn't have to be true. - // - // Further reading: https://lwn.net/Articles/342330/ \ - // "There is one little problem with that reasoning, though: NULL (zero) can - // actually be a valid pointer address." - let current_size_by_ptr = prev_pointer - fp; - - prev_pointer = fp; - // We choose the minimum between the function size given the pointer diff - // and the emitted size by the address map - let ptr = function_pointer; - let length = current_size_by_ptr; - (index, FunctionExtent { ptr: *ptr, length }) - })) - .collect::>() - }) - .unwrap_or_default(); - - // We sort them again, by key this time - function_pointers.sort_by(|(k1, _v1), (k2, _v2)| k1.cmp(k2)); - - let frame_infos = if self.metadata().function_frame_info.is_some() { - self.metadata().function_frame_info.clone().unwrap() - } else { - function_pointers - .iter() - .map(|(_, extent)| CompiledFunctionFrameInfo { - traps: vec![], - address_map: FunctionAddressMap { - body_len: extent.length, - ..Default::default() - }, - }) - .collect::>() - }; - - let finished_function_extents = function_pointers - .into_iter() - .map(|(_, function_extent)| function_extent) - .collect::>() - .into_boxed_slice(); - - *info = register_frame_info( - self.metadata.compile_info.module.clone(), - &finished_function_extents, - frame_infos, - ); - } - - fn finished_functions(&self) -> &BoxedSlice { - &self.finished_functions - } - - fn finished_function_call_trampolines(&self) -> &BoxedSlice { - &self.finished_function_call_trampolines - } - - fn finished_dynamic_function_trampolines(&self) -> &BoxedSlice { - &self.finished_dynamic_function_trampolines - } - - fn signatures(&self) -> &BoxedSlice { - &self.signatures - } - - fn func_data_registry(&self) -> &FuncDataRegistry { - &self.func_data_registry - } - - fn preinstantiate(&self) -> Result<(), InstantiationError> { - Ok(()) - } -} diff --git a/lib/engine-dylib/src/builder.rs b/lib/engine-dylib/src/builder.rs deleted file mode 100644 index b751f33e001..00000000000 --- a/lib/engine-dylib/src/builder.rs +++ /dev/null @@ -1,117 +0,0 @@ -use crate::DylibEngine; -use wasmer_compiler::{CompilerConfig, Features, Target}; - -/// The Dylib builder -pub struct Dylib { - compiler_config: Option>, - target: Option, - features: Option, -} - -impl Dylib { - #[cfg(feature = "compiler")] - /// Create a new Dylib builder. - pub fn new(compiler_config: T) -> Self - where - T: Into>, - { - let mut compiler_config = compiler_config.into(); - compiler_config.enable_pic(); - - Self { - compiler_config: Some(compiler_config), - target: None, - features: None, - } - } - - /// Create a new headless Dylib builder. - pub fn headless() -> Self { - Self { - compiler_config: None, - target: None, - features: None, - } - } - - /// Set the target - pub fn target(mut self, target: Target) -> Self { - self.target = Some(target); - self - } - - /// Set the features - pub fn features(mut self, features: Features) -> Self { - self.features = Some(features); - self - } - - /// Build the `DylibEngine` for this configuration - pub fn engine(self) -> DylibEngine { - if let Some(_compiler_config) = self.compiler_config { - #[cfg(feature = "compiler")] - { - let compiler_config = _compiler_config; - let target = self.target.unwrap_or_default(); - let features = self - .features - .unwrap_or_else(|| compiler_config.default_features_for_target(&target)); - let compiler = compiler_config.compiler(); - DylibEngine::new(compiler, target, features) - } - - #[cfg(not(feature = "compiler"))] - { - unreachable!("Cannot call `DylibEngine::new` without the `compiler` feature") - } - } else { - DylibEngine::headless() - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - #[cfg(feature = "compiler")] - use std::sync::Arc; - #[cfg(feature = "compiler")] - use wasmer_compiler::{Compiler, ModuleMiddleware}; - - #[cfg(feature = "compiler")] - #[derive(Default)] - pub struct TestCompilerConfig { - pub enabled_pic: bool, - pub middlewares: Vec>, - } - - #[cfg(feature = "compiler")] - impl CompilerConfig for TestCompilerConfig { - fn enable_pic(&mut self) { - self.enabled_pic = true; - } - - fn compiler(self: Box) -> Box { - unimplemented!("compiler not implemented"); - } - - fn push_middleware(&mut self, middleware: Arc) { - self.middlewares.push(middleware); - } - } - - #[cfg(feature = "compiler")] - #[test] - #[should_panic(expected = "compiler not implemented")] - fn build_engine() { - let compiler_config = TestCompilerConfig::default(); - let dylib = Dylib::new(compiler_config); - let _engine = dylib.engine(); - } - - #[test] - fn build_headless_engine() { - let dylib = Dylib::headless(); - let _engine = dylib.engine(); - } -} diff --git a/lib/engine-dylib/src/engine.rs b/lib/engine-dylib/src/engine.rs deleted file mode 100644 index f66159e4d1c..00000000000 --- a/lib/engine-dylib/src/engine.rs +++ /dev/null @@ -1,325 +0,0 @@ -//! Dylib Engine. - -use crate::DylibArtifact; -use libloading::Library; -use std::path::Path; -use std::sync::Arc; -use std::sync::Mutex; -use wasmer_compiler::{CompileError, Target}; -#[cfg(feature = "compiler")] -use wasmer_compiler::{Compiler, Triple}; -use wasmer_engine::{Artifact, DeserializeError, Engine, EngineId, Tunables}; -#[cfg(feature = "compiler")] -use wasmer_types::Features; -use wasmer_types::FunctionType; -use wasmer_vm::{ - FuncDataRegistry, SignatureRegistry, VMCallerCheckedAnyfunc, VMFuncRef, VMSharedSignatureIndex, -}; - -/// A WebAssembly `Dylib` Engine. -#[derive(Clone)] -pub struct DylibEngine { - inner: Arc>, - /// The target for the compiler - target: Arc, - engine_id: EngineId, -} - -impl DylibEngine { - /// Create a new `DylibEngine` with the given config - #[cfg(feature = "compiler")] - pub fn new(compiler: Box, target: Target, features: Features) -> Self { - let is_cross_compiling = *target.triple() != Triple::host(); - let linker = Linker::find_linker(is_cross_compiling); - - Self { - inner: Arc::new(Mutex::new(DylibEngineInner { - compiler: Some(compiler), - signatures: SignatureRegistry::new(), - func_data: Arc::new(FuncDataRegistry::new()), - prefixer: None, - features, - is_cross_compiling, - linker, - libraries: vec![], - })), - target: Arc::new(target), - engine_id: EngineId::default(), - } - } - - /// Create a headless `DylibEngine` - /// - /// A headless engine is an engine without any compiler attached. - /// This is useful for assuring a minimal runtime for running - /// WebAssembly modules. - /// - /// For example, for running in IoT devices where compilers are very - /// expensive, or also to optimize startup speed. - /// - /// # Important - /// - /// Headless engines can't compile or validate any modules, - /// they just take already processed Modules (via `Module::serialize`). - pub fn headless() -> Self { - Self { - inner: Arc::new(Mutex::new(DylibEngineInner { - #[cfg(feature = "compiler")] - compiler: None, - #[cfg(feature = "compiler")] - features: Features::default(), - signatures: SignatureRegistry::new(), - func_data: Arc::new(FuncDataRegistry::new()), - prefixer: None, - is_cross_compiling: false, - linker: Linker::None, - libraries: vec![], - })), - target: Arc::new(Target::default()), - engine_id: EngineId::default(), - } - } - - /// Sets a prefixer for the wasm module, so we can avoid any collisions - /// in the exported function names on the generated shared object. - /// - /// This, allows us to rather than have functions named `wasmer_function_1` - /// to be named `wasmer_function_PREFIX_1`. - /// - /// # Important - /// - /// This prefixer function should be deterministic, so the compilation - /// remains deterministic. - pub fn set_deterministic_prefixer(&mut self, prefixer: F) - where - F: Fn(&[u8]) -> String + Send + 'static, - { - let mut inner = self.inner_mut(); - inner.prefixer = Some(Box::new(prefixer)); - } - - pub(crate) fn inner(&self) -> std::sync::MutexGuard<'_, DylibEngineInner> { - self.inner.lock().unwrap() - } - - pub(crate) fn inner_mut(&self) -> std::sync::MutexGuard<'_, DylibEngineInner> { - self.inner.lock().unwrap() - } -} - -impl Engine for DylibEngine { - /// The target - fn target(&self) -> &Target { - &self.target - } - - /// Register a signature - fn register_signature(&self, func_type: &FunctionType) -> VMSharedSignatureIndex { - let compiler = self.inner(); - compiler.signatures().register(func_type) - } - - fn register_function_metadata(&self, func_data: VMCallerCheckedAnyfunc) -> VMFuncRef { - let compiler = self.inner(); - compiler.func_data().register(func_data) - } - - /// Lookup a signature - fn lookup_signature(&self, sig: VMSharedSignatureIndex) -> Option { - let compiler = self.inner(); - compiler.signatures().lookup(sig) - } - - /// Validates a WebAssembly module - fn validate(&self, binary: &[u8]) -> Result<(), CompileError> { - self.inner().validate(binary) - } - - /// Compile a WebAssembly binary - #[cfg(feature = "compiler")] - fn compile( - &self, - binary: &[u8], - tunables: &dyn Tunables, - ) -> Result, CompileError> { - Ok(Arc::new(DylibArtifact::new(self, binary, tunables)?)) - } - - /// Compile a WebAssembly binary (it will fail because the `compiler` flag is disabled). - #[cfg(not(feature = "compiler"))] - fn compile( - &self, - _binary: &[u8], - _tunables: &dyn Tunables, - ) -> Result, CompileError> { - Err(CompileError::Codegen( - "The `DylibEngine` is operating in headless mode, so it cannot compile a module." - .to_string(), - )) - } - - /// Deserializes a WebAssembly module (binary content of a shared object file) - unsafe fn deserialize(&self, bytes: &[u8]) -> Result, DeserializeError> { - Ok(Arc::new(DylibArtifact::deserialize(self, bytes)?)) - } - - /// Deserializes a WebAssembly module from a path - /// It should point to a shared object file generated by this engine. - unsafe fn deserialize_from_file( - &self, - file_ref: &Path, - ) -> Result, DeserializeError> { - Ok(Arc::new(DylibArtifact::deserialize_from_file( - self, file_ref, - )?)) - } - - fn id(&self) -> &EngineId { - &self.engine_id - } - - fn cloned(&self) -> Arc { - Arc::new(self.clone()) - } -} - -#[derive(Clone, Copy)] -pub(crate) enum Linker { - None, - Clang11, - Clang10, - Clang, - Gcc, -} - -impl Linker { - #[cfg(feature = "compiler")] - fn find_linker(is_cross_compiling: bool) -> Self { - let (possibilities, requirements): (&[_], _) = if is_cross_compiling { - ( - &[Self::Clang11, Self::Clang10, Self::Clang], - "at least one of `clang-11`, `clang-10`, or `clang`", - ) - } else { - (&[Self::Gcc], "`gcc`") - }; - *possibilities - .iter() - .find(|linker| which::which(linker.executable()).is_ok()) - .unwrap_or_else(|| { - panic!( - "Need {} installed in order to use `DylibEngine` when {}cross-compiling", - requirements, - if is_cross_compiling { "" } else { "not " } - ) - }) - } - - pub(crate) fn executable(self) -> &'static str { - match self { - Self::None => "", - Self::Clang11 => "clang-11", - Self::Clang10 => "clang-10", - Self::Clang => "clang", - Self::Gcc => "gcc", - } - } -} - -/// The inner contents of `DylibEngine` -pub struct DylibEngineInner { - /// The compiler - #[cfg(feature = "compiler")] - compiler: Option>, - - /// The WebAssembly features to use - #[cfg(feature = "compiler")] - features: Features, - - /// The signature registry is used mainly to operate with trampolines - /// performantly. - signatures: SignatureRegistry, - - /// The backing storage of `VMFuncRef`s. This centralized store ensures that 2 - /// functions with the same `VMCallerCheckedAnyfunc` will have the same `VMFuncRef`. - /// It also guarantees that the `VMFuncRef`s stay valid until the engine is dropped. - func_data: Arc, - - /// The prefixer returns the a String to prefix each of - /// the functions in the shared object generated by the `DylibEngine`, - /// so we can assure no collisions. - prefixer: Option String + Send>>, - - /// Whether the Dylib engine will cross-compile. - is_cross_compiling: bool, - - /// The linker to use. - linker: Linker, - - /// List of libraries loaded by this engine. - libraries: Vec, -} - -impl DylibEngineInner { - /// Gets the compiler associated to this engine. - #[cfg(feature = "compiler")] - pub fn compiler(&self) -> Result<&dyn Compiler, CompileError> { - if self.compiler.is_none() { - return Err(CompileError::Codegen("The `DylibEngine` is operating in headless mode, so it can only execute already compiled Modules.".to_string())); - } - Ok(&**self - .compiler - .as_ref() - .expect("Can't get compiler reference")) - } - - #[cfg(feature = "compiler")] - pub(crate) fn get_prefix(&self, bytes: &[u8]) -> String { - if let Some(prefixer) = &self.prefixer { - prefixer(bytes) - } else { - "".to_string() - } - } - - #[cfg(feature = "compiler")] - pub(crate) fn features(&self) -> &Features { - &self.features - } - - /// Validate the module - #[cfg(feature = "compiler")] - pub fn validate(&self, data: &[u8]) -> Result<(), CompileError> { - self.compiler()?.validate_module(self.features(), data) - } - - /// Validate the module - #[cfg(not(feature = "compiler"))] - pub fn validate<'data>(&self, _data: &'data [u8]) -> Result<(), CompileError> { - Err(CompileError::Validate( - "The `DylibEngine` is not compiled with compiler support, which is required for validating".to_string(), - )) - } - - /// Shared signature registry. - pub fn signatures(&self) -> &SignatureRegistry { - &self.signatures - } - - /// Shared func metadata registry. - pub(crate) fn func_data(&self) -> &Arc { - &self.func_data - } - - pub(crate) fn is_cross_compiling(&self) -> bool { - self.is_cross_compiling - } - - pub(crate) fn linker(&self) -> Linker { - self.linker - } - - pub(crate) fn add_library(&mut self, library: Library) { - self.libraries.push(library); - } -} diff --git a/lib/engine-dylib/src/lib.rs b/lib/engine-dylib/src/lib.rs deleted file mode 100644 index dfe566d5ff4..00000000000 --- a/lib/engine-dylib/src/lib.rs +++ /dev/null @@ -1,36 +0,0 @@ -//! Dylib Engine for Wasmer compilers. -//! -//! Given a compiler (such as `CraneliftCompiler` or `LLVMCompiler`) -//! it generates a dylib/shared object file (`.so` or `.dylib` -//! depending on the target), saves it temporarily to disk and uses it -//! natively via `dlopen` and `dlsym` (using the `libloading` -//! library). - -#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] -#![warn(unused_import_braces)] -#![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))] -#![cfg_attr( - feature = "cargo-clippy", - warn( - clippy::float_arithmetic, - clippy::mut_mut, - clippy::nonminimal_bool, - clippy::map_unwrap_or, - clippy::print_stdout, - clippy::unicode_not_nfc, - clippy::use_self - ) -)] - -mod artifact; -mod builder; -mod engine; -mod serialize; -mod trampoline; - -pub use crate::artifact::DylibArtifact; -pub use crate::builder::Dylib; -pub use crate::engine::DylibEngine; - -/// Version number of this crate. -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/lib/engine-dylib/src/serialize.rs b/lib/engine-dylib/src/serialize.rs deleted file mode 100644 index 0bb13c5cade..00000000000 --- a/lib/engine-dylib/src/serialize.rs +++ /dev/null @@ -1,139 +0,0 @@ -use rkyv::{ - archived_value, de::deserializers::SharedDeserializeMap, ser::serializers::AllocSerializer, - ser::Serializer as RkyvSerializer, Archive, Deserialize as RkyvDeserialize, - Serialize as RkyvSerialize, -}; -use serde::{Deserialize, Serialize}; -use std::error::Error; -use wasmer_compiler::{ - CompileError, CompileModuleInfo, CompiledFunctionFrameInfo, SectionIndex, Symbol, - SymbolRegistry, -}; -use wasmer_engine::DeserializeError; -use wasmer_types::entity::{EntityRef, PrimaryMap}; -use wasmer_types::{FunctionIndex, LocalFunctionIndex, OwnedDataInitializer, SignatureIndex}; - -fn to_compile_error(err: impl Error) -> CompileError { - CompileError::Codegen(format!("{}", err)) -} - -/// Serializable struct that represents the compiled metadata. -#[derive(Serialize, Deserialize, Debug, RkyvSerialize, RkyvDeserialize, Archive, PartialEq, Eq)] -pub struct ModuleMetadata { - pub compile_info: CompileModuleInfo, - pub function_frame_info: Option>, - pub prefix: String, - pub data_initializers: Box<[OwnedDataInitializer]>, - // The function body lengths (used to find function by address) - pub function_body_lengths: PrimaryMap, - pub cpu_features: u64, -} - -pub struct ModuleMetadataSymbolRegistry<'a> { - pub prefix: &'a String, -} - -impl ModuleMetadata { - pub fn split(&'_ mut self) -> (&'_ mut CompileModuleInfo, ModuleMetadataSymbolRegistry<'_>) { - let compile_info = &mut self.compile_info; - let symbol_registry = ModuleMetadataSymbolRegistry { - prefix: &self.prefix, - }; - (compile_info, symbol_registry) - } - - pub fn get_symbol_registry(&'_ self) -> ModuleMetadataSymbolRegistry<'_> { - ModuleMetadataSymbolRegistry { - prefix: &self.prefix, - } - } - - pub fn serialize(&mut self) -> Result, CompileError> { - let mut serializer = AllocSerializer::<4096>::default(); - let pos = serializer.serialize_value(self).map_err(to_compile_error)? as u64; - let mut serialized_data = serializer.into_serializer().into_inner(); - serialized_data.extend_from_slice(&pos.to_le_bytes()); - Ok(serialized_data.to_vec()) - } - - pub unsafe fn deserialize(metadata_slice: &[u8]) -> Result { - let archived = Self::archive_from_slice(metadata_slice)?; - Self::deserialize_from_archive(archived) - } - - unsafe fn archive_from_slice( - metadata_slice: &[u8], - ) -> Result<&ArchivedModuleMetadata, DeserializeError> { - let mut pos: [u8; 8] = Default::default(); - pos.copy_from_slice(&metadata_slice[metadata_slice.len() - 8..metadata_slice.len()]); - let pos: u64 = u64::from_le_bytes(pos); - Ok(archived_value::( - &metadata_slice[..metadata_slice.len() - 8], - pos as usize, - )) - } - - pub fn deserialize_from_archive( - archived: &ArchivedModuleMetadata, - ) -> Result { - let mut deserializer = SharedDeserializeMap::new(); - RkyvDeserialize::deserialize(archived, &mut deserializer) - .map_err(|e| DeserializeError::CorruptedBinary(format!("{:?}", e))) - } -} - -impl<'a> SymbolRegistry for ModuleMetadataSymbolRegistry<'a> { - fn symbol_to_name(&self, symbol: Symbol) -> String { - match symbol { - Symbol::LocalFunction(index) => { - format!("wasmer_function_{}_{}", self.prefix, index.index()) - } - Symbol::Section(index) => format!("wasmer_section_{}_{}", self.prefix, index.index()), - Symbol::FunctionCallTrampoline(index) => { - format!( - "wasmer_trampoline_function_call_{}_{}", - self.prefix, - index.index() - ) - } - Symbol::DynamicFunctionTrampoline(index) => { - format!( - "wasmer_trampoline_dynamic_function_{}_{}", - self.prefix, - index.index() - ) - } - } - } - - fn name_to_symbol(&self, name: &str) -> Option { - if let Some(index) = name.strip_prefix(&format!("wasmer_function_{}_", self.prefix)) { - index - .parse::() - .ok() - .map(|index| Symbol::LocalFunction(LocalFunctionIndex::from_u32(index))) - } else if let Some(index) = name.strip_prefix(&format!("wasmer_section_{}_", self.prefix)) { - index - .parse::() - .ok() - .map(|index| Symbol::Section(SectionIndex::from_u32(index))) - } else if let Some(index) = - name.strip_prefix(&format!("wasmer_trampoline_function_call_{}_", self.prefix)) - { - index - .parse::() - .ok() - .map(|index| Symbol::FunctionCallTrampoline(SignatureIndex::from_u32(index))) - } else if let Some(index) = name.strip_prefix(&format!( - "wasmer_trampoline_dynamic_function_{}_", - self.prefix - )) { - index - .parse::() - .ok() - .map(|index| Symbol::DynamicFunctionTrampoline(FunctionIndex::from_u32(index))) - } else { - None - } - } -} diff --git a/lib/engine-dylib/src/trampoline.rs b/lib/engine-dylib/src/trampoline.rs deleted file mode 100644 index 3254d270bbf..00000000000 --- a/lib/engine-dylib/src/trampoline.rs +++ /dev/null @@ -1,166 +0,0 @@ -//! Trampolines for libcalls. -//! -//! This is needed because the target of libcall relocations are not reachable -//! through normal branch instructions. -//! -//! There is an additional complexity for dynamic libraries: we can't just -//! import the symbol from the host executable because executables don't export -//! dynamic symbols (it's possible but requires special linker options). -//! -//! Instead, we export a table of function pointers in the data section which is -//! manually filled in by the runtime after the dylib is loaded. - -use enum_iterator::IntoEnumIterator; -use object::{ - elf, macho, - write::{Object, Relocation, SectionId, StandardSection, Symbol, SymbolId, SymbolSection}, - BinaryFormat, RelocationEncoding, RelocationKind, SymbolFlags, SymbolKind, SymbolScope, -}; -use wasmer_compiler::{Architecture, Target}; -use wasmer_vm::libcalls::{function_pointer, LibCall}; - -/// Symbol exported from the dynamic library which points to the trampoline table. -pub const WASMER_TRAMPOLINES_SYMBOL: &[u8] = b"WASMER_TRAMPOLINES"; - -// SystemV says that both x16 and x17 are available as intra-procedural scratch -// registers but Apple's ABI restricts us to use x17. -// ADRP x17, #... 11 00 00 90 -// LDR x17, [x17, #...] 31 02 40 f9 -// BR x17 20 02 1f d6 -const AARCH64_TRAMPOLINE: [u8; 12] = [ - 0x11, 0x00, 0x00, 0x90, 0x31, 0x02, 0x40, 0xf9, 0x20, 0x02, 0x1f, 0xd6, -]; - -// JMP [RIP + ...] FF 25 00 00 00 00 -const X86_64_TRAMPOLINE: [u8; 6] = [0xff, 0x25, 0x00, 0x00, 0x00, 0x00]; - -fn emit_trampoline( - obj: &mut Object, - text: SectionId, - trampoline_table_symbols: &[SymbolId], - libcall: LibCall, - target: &Target, -) { - let function_name = libcall.to_function_name(); - let libcall_symbol = obj.add_symbol(Symbol { - name: function_name.as_bytes().to_vec(), - value: 0, - size: 0, - kind: SymbolKind::Text, - scope: SymbolScope::Linkage, - weak: false, - section: SymbolSection::Section(text), - flags: SymbolFlags::None, - }); - - match target.triple().architecture { - Architecture::Aarch64(_) => { - let (reloc1, reloc2) = match obj.format() { - BinaryFormat::Elf => ( - RelocationKind::Elf(elf::R_AARCH64_ADR_PREL_PG_HI21), - RelocationKind::Elf(elf::R_AARCH64_LDST64_ABS_LO12_NC), - ), - BinaryFormat::MachO => ( - RelocationKind::MachO { - value: macho::ARM64_RELOC_PAGE21, - relative: true, - }, - RelocationKind::MachO { - value: macho::ARM64_RELOC_PAGEOFF12, - relative: false, - }, - ), - _ => panic!("Unsupported binary format on AArch64"), - }; - let offset = obj.add_symbol_data(libcall_symbol, text, &AARCH64_TRAMPOLINE, 4); - obj.add_relocation( - text, - Relocation { - offset, - size: 32, - kind: reloc1, - encoding: RelocationEncoding::Generic, - symbol: trampoline_table_symbols[libcall as usize], - addend: 0, - }, - ) - .unwrap(); - obj.add_relocation( - text, - Relocation { - offset: offset + 4, - size: 32, - kind: reloc2, - encoding: RelocationEncoding::Generic, - symbol: trampoline_table_symbols[libcall as usize], - addend: 0, - }, - ) - .unwrap(); - } - Architecture::X86_64 => { - let offset = obj.add_symbol_data(libcall_symbol, text, &X86_64_TRAMPOLINE, 1); - obj.add_relocation( - text, - Relocation { - offset: offset + 2, - size: 32, - kind: RelocationKind::Relative, - encoding: RelocationEncoding::Generic, - symbol: trampoline_table_symbols[libcall as usize], - // -4 because RIP-relative addressing starts from the end of - // the instruction. - addend: -4, - }, - ) - .unwrap(); - } - arch => panic!("Unsupported architecture: {}", arch), - }; -} - -/// Emits the libcall trampolines and table to the object file. -pub fn emit_trampolines(obj: &mut Object, target: &Target) { - let text = obj.section_id(StandardSection::Text); - let bss = obj.section_id(StandardSection::UninitializedData); - - let trampoline_table = obj.add_symbol(Symbol { - name: WASMER_TRAMPOLINES_SYMBOL.to_vec(), - value: 0, - size: 0, - kind: SymbolKind::Data, - scope: SymbolScope::Dynamic, - weak: false, - section: SymbolSection::Section(bss), - flags: SymbolFlags::None, - }); - let table_offset = - obj.add_symbol_bss(trampoline_table, bss, LibCall::VARIANT_COUNT as u64 * 8, 8); - - // Create a symbol for each entry in the table. We could avoid this and use - // an addend, but this isn't supported in all object formats. - let mut trampoline_table_symbols = vec![]; - for libcall in LibCall::into_enum_iter() { - trampoline_table_symbols.push(obj.add_symbol(Symbol { - name: format!("__WASMER_TRAMPOLINE{}", libcall as usize).into_bytes(), - value: table_offset + libcall as u64 * 8, - size: 0, - kind: SymbolKind::Data, - scope: SymbolScope::Compilation, - weak: false, - section: SymbolSection::Section(bss), - flags: SymbolFlags::None, - })); - } - - for libcall in LibCall::into_enum_iter() { - emit_trampoline(obj, text, &trampoline_table_symbols, libcall, target); - } -} - -/// Fills in the libcall trampoline table at the given address. -pub unsafe fn fill_trampoline_table(table: *mut usize) { - for libcall in LibCall::into_enum_iter() { - *table.add(libcall as usize) = function_pointer(libcall); - } -} diff --git a/lib/engine-staticlib/Cargo.toml b/lib/engine-staticlib/Cargo.toml deleted file mode 100644 index 2fbe8d55bf0..00000000000 --- a/lib/engine-staticlib/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "wasmer-engine-staticlib" -version = "2.3.0" -authors = ["Wasmer Engineering Team "] -description = "Wasmer Staticlib Engine" -categories = ["wasm"] -keywords = ["webassembly", "wasm"] -repository = "https://github.com/wasmerio/wasmer" -license = "MIT" -readme = "README.md" -edition = "2018" - -[dependencies] -wasmer-artifact = { path = "../artifact", version = "=2.3.0" } -wasmer-types = { path = "../types", version = "=2.3.0" } -wasmer-compiler = { path = "../compiler", version = "=2.3.0" } -wasmer-vm = { path = "../vm", version = "=2.3.0" } -wasmer-engine = { path = "../engine", version = "=2.3.0" } -wasmer-object = { path = "../object", version = "=2.3.0" } -serde = { version = "1.0", features = ["derive", "rc"] } -cfg-if = "1.0" -tracing = "0.1" -bincode = "1.3" -leb128 = "0.2" -libloading = "0.7" -tempfile = "3.1" -enumset = "1.0" - -[features] -# Enable the `compiler` feature if you want the engine to compile -# and not be only on headless mode. -compiler = ["wasmer-compiler/translator"] - -[badges] -maintenance = { status = "actively-developed" } diff --git a/lib/engine-staticlib/README.md b/lib/engine-staticlib/README.md deleted file mode 100644 index e8566f0137b..00000000000 --- a/lib/engine-staticlib/README.md +++ /dev/null @@ -1,139 +0,0 @@ -# Wasmer Engine Staticlib - -This is an [engine](https://crates.io/crates/wasmer-engine) for the -[wasmer](https://crates.io/crates/wasmer) WebAssembly VM. - -This engine is used to produce a native static object library that can -be linked against providing a sandboxed WebAssembly runtime -environment for the compiled module with no need for runtime -compilation. - -## Example of use - -First we compile our WebAssembly file with Wasmer - -```sh -wasmer compile path/to/wasm/file.wasm --llvm --staticlib -o my_wasm.o --header my_wasm.h -``` - -You will then see output like: - -``` -Engine: staticlib -Compiler: llvm -Target: x86_64-apple-darwin -✔ File compiled successfully to `my_wasm.o`. -✔ Header file generated successfully at `my_wasm.h`. -``` - -Now let's create a program to link with this static object file. - -```c -#include "wasmer.h" -#include "my_wasm.h" - -#include -#include - -#define own - -static void print_wasmer_error() -{ - int error_len = wasmer_last_error_length(); - if (error_len > 0) { - printf("Error len: `%d`\n", error_len); - char* error_str = (char*) malloc(error_len); - wasmer_last_error_message(error_str, error_len); - printf("Error str: `%s`\n", error_str); - free(error_str); - } -} - -int main() { - printf("Initializing...\n"); - wasm_config_t* config = wasm_config_new(); - wasm_config_set_engine(config, STATICLIB); - wasm_engine_t* engine = wasm_engine_new_with_config(config); - wasm_store_t* store = wasm_store_new(engine); - - wasm_module_t* module = wasmer_staticlib_engine_new(store, "qjs.wasm"); - if (!module) { - printf("Failed to create module\n"); - print_wasmer_error(); - return -1; - } - - // We have now finished the memory buffer book keeping and we have a valid Module. - - // In this example we're passing some JavaScript source code as a command line argument - // to a WASI module that can evaluate JavaScript. - wasi_config_t* wasi_config = wasi_config_new("constant_value_here"); - const char* js_string = "function greet(name) { return JSON.stringify('Hello, ' + name); }; print(greet('World'));"; - wasi_config_arg(wasi_config, "--eval"); - wasi_config_arg(wasi_config, js_string); - wasi_env_t* wasi_env = wasi_env_new(wasi_config); - if (!wasi_env) { - printf("> Error building WASI env!\n"); - print_wasmer_error(); - return 1; - } - - wasm_importtype_vec_t import_types; - wasm_module_imports(module, &import_types); - int num_imports = import_types.size; - wasm_extern_t** imports = (wasm_extern_t**) malloc(num_imports * sizeof(wasm_extern_t*)); - wasm_importtype_vec_delete(&import_types); - - bool get_imports_result = wasi_get_imports(store, module, wasi_env, imports); - wasi_env_delete(wasi_env); - if (!get_imports_result) { - printf("> Error getting WASI imports!\n"); - print_wasmer_error(); - return 1; - } - - wasm_instance_t* instance = wasm_instance_new(store, module, (const wasm_extern_t* const*) imports, NULL); - if (! instance) { - printf("Failed to create instance\n"); - print_wasmer_error(); - return -1; - } - - // WASI is now set up. - own wasm_func_t* start_function = wasi_get_start_function(instance); - if (!start_function) { - fprintf(stderr, "`_start` function not found\n"); - print_wasmer_error(); - return -1; - } - - fflush(stdout); - own wasm_trap_t* trap = wasm_func_call(start_function, NULL, NULL); - if (trap) { - fprintf(stderr, "Trap is not NULL: TODO:\n"); - return -1; - } - - wasm_instance_delete(instance); - wasm_module_delete(module); - wasm_store_delete(store); - wasm_engine_delete(engine); - return 0; -} -``` - -We save that source code into `test.c` and run: - -```sh -clang -O2 -c test.c -o test.o -``` - -Now we just need to link everything together: - -```sh -clang -O2 test.o my_wasm.o libwasmer.a -``` - -We link the static object file we created with our C code, the object -file we generated with Wasmer, and `libwasmer` together and produce an -executable that can call into our compiled WebAssembly! diff --git a/lib/engine-staticlib/src/artifact.rs b/lib/engine-staticlib/src/artifact.rs deleted file mode 100644 index 9d98ce1e2a1..00000000000 --- a/lib/engine-staticlib/src/artifact.rs +++ /dev/null @@ -1,509 +0,0 @@ -//! Define `StaticlibArtifact` to allow compiling and instantiating to be -//! done as separate steps. - -use crate::engine::{StaticlibEngine, StaticlibEngineInner}; -use crate::serialize::{ModuleMetadata, ModuleMetadataSymbolRegistry}; -use enumset::EnumSet; -use std::collections::BTreeMap; -use std::error::Error; -use std::mem; -use std::sync::Arc; -use wasmer_artifact::ArtifactCreate; -use wasmer_compiler::{ - CompileError, CpuFeature, Features, OperatingSystem, SymbolRegistry, Triple, -}; -#[cfg(feature = "compiler")] -use wasmer_compiler::{ - CompileModuleInfo, Compiler, FunctionBodyData, ModuleEnvironment, ModuleMiddlewareChain, - ModuleTranslationState, -}; -use wasmer_engine::{ - Artifact, DeserializeError, InstantiationError, MetadataHeader, SerializeError, -}; -#[cfg(feature = "compiler")] -use wasmer_engine::{Engine, Tunables}; -#[cfg(feature = "compiler")] -use wasmer_object::{emit_compilation, emit_data, get_object_for_target}; -use wasmer_types::entity::EntityRef; -use wasmer_types::entity::{BoxedSlice, PrimaryMap}; -#[cfg(feature = "compiler")] -use wasmer_types::DataInitializer; -use wasmer_types::{ - FunctionIndex, LocalFunctionIndex, MemoryIndex, ModuleInfo, OwnedDataInitializer, - SignatureIndex, TableIndex, -}; -use wasmer_vm::{ - FuncDataRegistry, FunctionBodyPtr, MemoryStyle, TableStyle, VMSharedSignatureIndex, - VMTrampoline, -}; - -/// A compiled wasm module, ready to be instantiated. -pub struct StaticlibArtifact { - metadata: ModuleMetadata, - module_bytes: Vec, - finished_functions: BoxedSlice, - finished_function_call_trampolines: BoxedSlice, - finished_dynamic_function_trampolines: BoxedSlice, - signatures: BoxedSlice, - func_data_registry: Arc, - /// Length of the serialized metadata - metadata_length: usize, - symbol_registry: ModuleMetadataSymbolRegistry, - is_compiled: bool, -} - -#[allow(dead_code)] -fn to_compile_error(err: impl Error) -> CompileError { - CompileError::Codegen(format!("{}", err)) -} - -#[allow(dead_code)] -const WASMER_METADATA_SYMBOL: &[u8] = b"WASMER_METADATA"; - -impl StaticlibArtifact { - // Mach-O header in Mac - #[allow(dead_code)] - const MAGIC_HEADER_MH_CIGAM_64: &'static [u8] = &[207, 250, 237, 254]; - - // ELF Magic header for Linux (32 bit) - #[allow(dead_code)] - const MAGIC_HEADER_ELF_32: &'static [u8] = &[0x7f, b'E', b'L', b'F', 1]; - - // ELF Magic header for Linux (64 bit) - #[allow(dead_code)] - const MAGIC_HEADER_ELF_64: &'static [u8] = &[0x7f, b'E', b'L', b'F', 2]; - - // COFF Magic header for Windows (64 bit) - #[allow(dead_code)] - const MAGIC_HEADER_COFF_64: &'static [u8] = &[b'M', b'Z']; - - /// Check if the provided bytes look like `StaticlibArtifact`. - /// - /// This means, if the bytes look like a static object file in the - /// target system. - pub fn is_deserializable(bytes: &[u8]) -> bool { - cfg_if::cfg_if! { - if #[cfg(all(target_pointer_width = "64", target_vendor="apple"))] { - bytes.starts_with(Self::MAGIC_HEADER_MH_CIGAM_64) - } - else if #[cfg(all(target_pointer_width = "64", target_os="linux"))] { - bytes.starts_with(Self::MAGIC_HEADER_ELF_64) - } - else if #[cfg(all(target_pointer_width = "32", target_os="linux"))] { - bytes.starts_with(Self::MAGIC_HEADER_ELF_32) - } - else if #[cfg(all(target_pointer_width = "64", target_os="windows"))] { - bytes.starts_with(Self::MAGIC_HEADER_COFF_64) - } - else { - false - } - } - } - - #[cfg(feature = "compiler")] - #[allow(clippy::type_complexity)] - /// Generate a compilation - fn generate_metadata<'data>( - data: &'data [u8], - features: &Features, - compiler: &dyn Compiler, - tunables: &dyn Tunables, - ) -> Result< - ( - CompileModuleInfo, - PrimaryMap>, - Vec>, - Option, - ), - CompileError, - > { - let environ = ModuleEnvironment::new(); - let translation = environ.translate(data).map_err(CompileError::Wasm)?; - - // We try to apply the middleware first - let mut module = translation.module; - let middlewares = compiler.get_middlewares(); - middlewares.apply_on_module_info(&mut module); - - let memory_styles: PrimaryMap = module - .memories - .values() - .map(|memory_type| tunables.memory_style(memory_type)) - .collect(); - let table_styles: PrimaryMap = module - .tables - .values() - .map(|table_type| tunables.table_style(table_type)) - .collect(); - - let compile_info = CompileModuleInfo { - module: Arc::new(module), - features: features.clone(), - memory_styles, - table_styles, - }; - Ok(( - compile_info, - translation.function_body_inputs, - translation.data_initializers, - translation.module_translation_state, - )) - } - - /// Compile a data buffer into a `StaticlibArtifact`, which can be statically linked against - /// and run later. - #[cfg(feature = "compiler")] - pub fn new( - engine: &StaticlibEngine, - data: &[u8], - tunables: &dyn Tunables, - ) -> Result { - let mut engine_inner = engine.inner_mut(); - let target = engine.target(); - let compiler = engine_inner.compiler()?; - let (compile_info, function_body_inputs, data_initializers, module_translation) = - Self::generate_metadata(data, engine_inner.features(), compiler, tunables)?; - - let data_initializers = data_initializers - .iter() - .map(OwnedDataInitializer::new) - .collect::>() - .into_boxed_slice(); - - let target_triple = target.triple(); - - // TODO: we currently supply all-zero function body lengths. - // We don't know the lengths until they're compiled, yet we have to - // supply the metadata as an input to the compile. - let function_body_lengths = function_body_inputs - .keys() - .map(|_function_body| 0u64) - .collect::>(); - - let mut metadata = ModuleMetadata { - compile_info, - prefix: engine_inner.get_prefix(data), - data_initializers, - function_body_lengths, - cpu_features: target.cpu_features().as_u64(), - }; - - /* - In the C file we need: - - imports - - exports - - to construct an api::Module which is a Store (can be passed in via argument) and an - Arc which means this struct which includes: - - CompileModuleInfo - - Features - - ModuleInfo - - MemoryIndex -> MemoryStyle - - TableIndex -> TableStyle - - LocalFunctionIndex -> FunctionBodyPtr // finished functions - - FunctionIndex -> FunctionBodyPtr // finished dynamic function trampolines - - SignatureIndex -> VMSharedSignatureindextureIndex // signatures - */ - - let serialized_data = bincode::serialize(&metadata).map_err(to_compile_error)?; - let mut metadata_binary = vec![]; - metadata_binary.extend(MetadataHeader::new(serialized_data.len()).into_bytes()); - metadata_binary.extend(serialized_data); - let metadata_length = metadata_binary.len(); - - let (compile_info, symbol_registry) = metadata.split(); - - let mut module = (*compile_info.module).clone(); - let middlewares = compiler.get_middlewares(); - middlewares.apply_on_module_info(&mut module); - compile_info.module = Arc::new(module); - - let maybe_obj_bytes = compiler.experimental_native_compile_module( - target, - compile_info, - module_translation.as_ref().unwrap(), - &function_body_inputs, - &symbol_registry, - &metadata_binary, - ); - - let obj_bytes = if let Some(obj_bytes) = maybe_obj_bytes { - obj_bytes? - } else { - let compilation = compiler.compile_module( - target, - &metadata.compile_info, - module_translation.as_ref().unwrap(), - function_body_inputs, - )?; - // there's an ordering issue, but we can update function_body_lengths here. - /* - // We construct the function body lengths - let function_body_lengths = compilation - .get_function_bodies() - .values() - .map(|function_body| function_body.body.len() as u64) - .collect::>(); - */ - let mut obj = get_object_for_target(target_triple).map_err(to_compile_error)?; - emit_data(&mut obj, WASMER_METADATA_SYMBOL, &metadata_binary, 1) - .map_err(to_compile_error)?; - emit_compilation(&mut obj, compilation, &symbol_registry, target_triple) - .map_err(to_compile_error)?; - obj.write().map_err(to_compile_error)? - }; - - Self::from_parts_crosscompiled(&mut *engine_inner, metadata, obj_bytes, metadata_length) - } - - /// Get the default extension when serializing this artifact - pub fn get_default_extension(triple: &Triple) -> &'static str { - match triple.operating_system { - OperatingSystem::Windows => "obj", - _ => "o", - } - } - - /// Construct a `StaticlibArtifact` from component parts. - pub fn from_parts_crosscompiled( - engine_inner: &mut StaticlibEngineInner, - metadata: ModuleMetadata, - module_bytes: Vec, - metadata_length: usize, - ) -> Result { - let finished_functions: PrimaryMap = PrimaryMap::new(); - let finished_function_call_trampolines: PrimaryMap = - PrimaryMap::new(); - let finished_dynamic_function_trampolines: PrimaryMap = - PrimaryMap::new(); - let signature_registry = engine_inner.signatures(); - let signatures = metadata - .compile_info - .module - .signatures - .values() - .map(|sig| signature_registry.register(sig)) - .collect::>(); - - let symbol_registry = metadata.get_symbol_registry(); - Ok(Self { - metadata, - module_bytes, - finished_functions: finished_functions.into_boxed_slice(), - finished_function_call_trampolines: finished_function_call_trampolines - .into_boxed_slice(), - finished_dynamic_function_trampolines: finished_dynamic_function_trampolines - .into_boxed_slice(), - signatures: signatures.into_boxed_slice(), - func_data_registry: engine_inner.func_data().clone(), - metadata_length, - symbol_registry, - is_compiled: true, - }) - } - - /// Compile a data buffer into a `StaticlibArtifact`, which may then be instantiated. - #[cfg(not(feature = "compiler"))] - pub fn new(_engine: &StaticlibEngine, _data: &[u8]) -> Result { - Err(CompileError::Codegen( - "Compilation is not enabled in the engine".to_string(), - )) - } - - /// Deserialize a `StaticlibArtifact` from bytes. - /// - /// # Safety - /// - /// The bytes must represent a serialized WebAssembly module. - pub unsafe fn deserialize( - engine: &StaticlibEngine, - bytes: &[u8], - ) -> Result { - let metadata_len = MetadataHeader::parse(bytes)?; - - let metadata: ModuleMetadata = - bincode::deserialize(&bytes[MetadataHeader::LEN..][..metadata_len]).unwrap(); - - const WORD_SIZE: usize = mem::size_of::(); - let mut byte_buffer = [0u8; WORD_SIZE]; - - let mut cur_offset = MetadataHeader::LEN + metadata_len; - byte_buffer[0..WORD_SIZE].clone_from_slice(&bytes[cur_offset..(cur_offset + WORD_SIZE)]); - cur_offset += WORD_SIZE; - - let num_finished_functions = usize::from_ne_bytes(byte_buffer); - let mut finished_functions = PrimaryMap::new(); - - let engine_inner = engine.inner(); - let signature_registry = engine_inner.signatures(); - let func_data_registry = engine_inner.func_data().clone(); - let mut sig_map: BTreeMap = BTreeMap::new(); - - let num_imported_functions = metadata.compile_info.module.num_imported_functions; - // set up the imported functions first... - for i in 0..num_imported_functions { - let sig_idx = metadata.compile_info.module.functions[FunctionIndex::new(i)]; - let func_type = &metadata.compile_info.module.signatures[sig_idx]; - let vm_shared_idx = signature_registry.register(func_type); - sig_map.insert(sig_idx, vm_shared_idx); - } - // read finished functions in order now... - for i in 0..num_finished_functions { - let local_func_idx = LocalFunctionIndex::new(i); - let func_idx = metadata.compile_info.module.func_index(local_func_idx); - let sig_idx = metadata.compile_info.module.functions[func_idx]; - let func_type = &metadata.compile_info.module.signatures[sig_idx]; - let vm_shared_idx = signature_registry.register(func_type); - sig_map.insert(sig_idx, vm_shared_idx); - - byte_buffer[0..WORD_SIZE] - .clone_from_slice(&bytes[cur_offset..(cur_offset + WORD_SIZE)]); - let fp = FunctionBodyPtr(usize::from_ne_bytes(byte_buffer) as _); - cur_offset += WORD_SIZE; - - // TODO: we can read back the length here if we serialize it. This will improve debug output. - - finished_functions.push(fp); - } - - let mut signatures: PrimaryMap<_, VMSharedSignatureIndex> = PrimaryMap::new(); - for i in 0..(sig_map.len()) { - if let Some(shared_idx) = sig_map.get(&SignatureIndex::new(i)) { - signatures.push(*shared_idx); - } else { - panic!("Invalid data, missing sig idx; TODO: handle this error"); - } - } - - // read trampolines in order - let mut finished_function_call_trampolines = PrimaryMap::new(); - byte_buffer[0..WORD_SIZE].clone_from_slice(&bytes[cur_offset..(cur_offset + WORD_SIZE)]); - cur_offset += WORD_SIZE; - let num_function_trampolines = usize::from_ne_bytes(byte_buffer); - for _ in 0..num_function_trampolines { - byte_buffer[0..WORD_SIZE] - .clone_from_slice(&bytes[cur_offset..(cur_offset + WORD_SIZE)]); - cur_offset += WORD_SIZE; - let trampoline_ptr_bytes = usize::from_ne_bytes(byte_buffer); - let trampoline = mem::transmute::(trampoline_ptr_bytes); - finished_function_call_trampolines.push(trampoline); - // TODO: we can read back the length here if we serialize it. This will improve debug output. - } - - // read dynamic function trampolines in order now... - let mut finished_dynamic_function_trampolines = PrimaryMap::new(); - byte_buffer[0..WORD_SIZE].clone_from_slice(&bytes[cur_offset..(cur_offset + WORD_SIZE)]); - cur_offset += WORD_SIZE; - let num_dynamic_trampoline_functions = usize::from_ne_bytes(byte_buffer); - for _i in 0..num_dynamic_trampoline_functions { - byte_buffer[0..WORD_SIZE] - .clone_from_slice(&bytes[cur_offset..(cur_offset + WORD_SIZE)]); - let fp = FunctionBodyPtr(usize::from_ne_bytes(byte_buffer) as _); - cur_offset += WORD_SIZE; - - // TODO: we can read back the length here if we serialize it. This will improve debug output. - - finished_dynamic_function_trampolines.push(fp); - } - - let symbol_registry = metadata.get_symbol_registry(); - Ok(Self { - metadata, - module_bytes: bytes.to_owned(), - finished_functions: finished_functions.into_boxed_slice(), - finished_function_call_trampolines: finished_function_call_trampolines - .into_boxed_slice(), - finished_dynamic_function_trampolines: finished_dynamic_function_trampolines - .into_boxed_slice(), - signatures: signatures.into_boxed_slice(), - func_data_registry, - metadata_length: 0, - symbol_registry, - is_compiled: false, - }) - } - - /// Get the `SymbolRegistry` used to generate the names used in the Artifact. - pub fn symbol_registry(&self) -> &dyn SymbolRegistry { - &self.symbol_registry - } - - /// The length in bytes of the metadata in the serialized output. - pub fn metadata_length(&self) -> usize { - self.metadata_length - } -} - -impl ArtifactCreate for StaticlibArtifact { - fn module(&self) -> Arc { - self.metadata.compile_info.module.clone() - } - - fn module_ref(&self) -> &ModuleInfo { - &self.metadata.compile_info.module - } - - fn module_mut(&mut self) -> Option<&mut ModuleInfo> { - Arc::get_mut(&mut self.metadata.compile_info.module) - } - - fn features(&self) -> &Features { - &self.metadata.compile_info.features - } - - fn cpu_features(&self) -> EnumSet { - EnumSet::from_u64(self.metadata.cpu_features) - } - - fn data_initializers(&self) -> &[OwnedDataInitializer] { - &*self.metadata.data_initializers - } - - fn memory_styles(&self) -> &PrimaryMap { - &self.metadata.compile_info.memory_styles - } - - fn table_styles(&self) -> &PrimaryMap { - &self.metadata.compile_info.table_styles - } - - /// Serialize a StaticlibArtifact - fn serialize(&self) -> Result, SerializeError> { - Ok(self.module_bytes.clone()) - } -} -impl Artifact for StaticlibArtifact { - fn register_frame_info(&self) { - // Do nothing for now - } - - fn finished_functions(&self) -> &BoxedSlice { - &self.finished_functions - } - - fn finished_function_call_trampolines(&self) -> &BoxedSlice { - &self.finished_function_call_trampolines - } - - fn finished_dynamic_function_trampolines(&self) -> &BoxedSlice { - &self.finished_dynamic_function_trampolines - } - - fn signatures(&self) -> &BoxedSlice { - &self.signatures - } - - fn func_data_registry(&self) -> &FuncDataRegistry { - &self.func_data_registry - } - fn preinstantiate(&self) -> Result<(), InstantiationError> { - if self.is_compiled { - panic!( - "a module built with the staticlib engine must be linked \ - into the current executable" - ); - } - Ok(()) - } -} diff --git a/lib/engine-staticlib/src/builder.rs b/lib/engine-staticlib/src/builder.rs deleted file mode 100644 index 1f0a4f7eb6b..00000000000 --- a/lib/engine-staticlib/src/builder.rs +++ /dev/null @@ -1,117 +0,0 @@ -use crate::StaticlibEngine; -use wasmer_compiler::{CompilerConfig, Features, Target}; - -/// The Staticlib builder -pub struct Staticlib { - compiler_config: Option>, - target: Option, - features: Option, -} - -impl Staticlib { - #[cfg(feature = "compiler")] - /// Create a new Staticlib - pub fn new(compiler_config: T) -> Self - where - T: Into>, - { - let mut compiler_config = compiler_config.into(); - compiler_config.enable_pic(); - - Self { - compiler_config: Some(compiler_config), - target: None, - features: None, - } - } - - /// Create a new headless Staticlib - pub fn headless() -> Self { - Self { - compiler_config: None, - target: None, - features: None, - } - } - - /// Set the target - pub fn target(mut self, target: Target) -> Self { - self.target = Some(target); - self - } - - /// Set the features - pub fn features(mut self, features: Features) -> Self { - self.features = Some(features); - self - } - - /// Build the `StaticlibEngine` for this configuration - pub fn engine(self) -> StaticlibEngine { - if let Some(_compiler_config) = self.compiler_config { - #[cfg(feature = "compiler")] - { - let compiler_config = _compiler_config; - let target = self.target.unwrap_or_default(); - let features = self - .features - .unwrap_or_else(|| compiler_config.default_features_for_target(&target)); - let compiler = compiler_config.compiler(); - StaticlibEngine::new(compiler, target, features) - } - - #[cfg(not(feature = "compiler"))] - { - unreachable!("Cannot call `StaticlibEngine::new` without the `compiler` feature") - } - } else { - StaticlibEngine::headless() - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - #[cfg(feature = "compiler")] - use std::sync::Arc; - #[cfg(feature = "compiler")] - use wasmer_compiler::{Compiler, ModuleMiddleware}; - - #[cfg(feature = "compiler")] - #[derive(Default)] - pub struct TestCompilerConfig { - pub enabled_pic: bool, - pub middlewares: Vec>, - } - - #[cfg(feature = "compiler")] - impl CompilerConfig for TestCompilerConfig { - fn enable_pic(&mut self) { - self.enabled_pic = true; - } - - fn compiler(self: Box) -> Box { - unimplemented!("compiler not implemented"); - } - - fn push_middleware(&mut self, middleware: Arc) { - self.middlewares.push(middleware); - } - } - - #[cfg(feature = "compiler")] - #[test] - #[should_panic(expected = "compiler not implemented")] - fn build_engine() { - let compiler_config = TestCompilerConfig::default(); - let staticlib = Staticlib::new(compiler_config); - let _engine = staticlib.engine(); - } - - #[test] - fn build_headless_engine() { - let staticlib = Staticlib::headless(); - let _engine = staticlib.engine(); - } -} diff --git a/lib/engine-staticlib/src/engine.rs b/lib/engine-staticlib/src/engine.rs deleted file mode 100644 index 70799fe294a..00000000000 --- a/lib/engine-staticlib/src/engine.rs +++ /dev/null @@ -1,254 +0,0 @@ -use crate::StaticlibArtifact; -use std::io::Read; -use std::path::Path; -use std::sync::{Arc, Mutex}; -#[cfg(feature = "compiler")] -use wasmer_compiler::Compiler; -use wasmer_compiler::{CompileError, Target}; -use wasmer_engine::{Artifact, DeserializeError, Engine, EngineId, Tunables}; -#[cfg(feature = "compiler")] -use wasmer_types::Features; -use wasmer_types::FunctionType; -use wasmer_vm::{ - FuncDataRegistry, SignatureRegistry, VMCallerCheckedAnyfunc, VMFuncRef, VMSharedSignatureIndex, -}; - -/// A WebAssembly `Staticlib` Engine. -#[derive(Clone)] -pub struct StaticlibEngine { - inner: Arc>, - /// The target for the compiler - target: Arc, - engine_id: EngineId, -} - -impl StaticlibEngine { - /// Create a new `StaticlibEngine` with the given config - #[cfg(feature = "compiler")] - pub fn new(compiler: Box, target: Target, features: Features) -> Self { - Self { - inner: Arc::new(Mutex::new(StaticlibEngineInner { - compiler: Some(compiler), - signatures: SignatureRegistry::new(), - func_data: Arc::new(FuncDataRegistry::new()), - prefixer: None, - features, - })), - target: Arc::new(target), - engine_id: EngineId::default(), - } - } - - /// Create a headless `StaticlibEngine` - /// - /// A headless engine is an engine without any compiler attached. - /// This is useful for assuring a minimal runtime for running - /// WebAssembly modules. - /// - /// For example, for running in IoT devices where compilers are very - /// expensive, or also to optimize startup speed. - /// - /// # Important - /// - /// Headless engines can't compile or validate any modules, - /// they just take already processed Modules (via `Module::serialize`). - pub fn headless() -> Self { - Self { - inner: Arc::new(Mutex::new(StaticlibEngineInner { - #[cfg(feature = "compiler")] - compiler: None, - #[cfg(feature = "compiler")] - features: Features::default(), - signatures: SignatureRegistry::new(), - func_data: Arc::new(FuncDataRegistry::new()), - prefixer: None, - })), - target: Arc::new(Target::default()), - engine_id: EngineId::default(), - } - } - - /// Sets a prefixer for the Wasm module, so we can avoid any - /// collisions in the exported function names on the generated - /// object. - /// - /// This, allows us to rather than have functions named - /// `wasmer_function_1` to be named `wasmer_function_PREFIX_1`. - /// - /// # Important - /// - /// This prefixer function should be deterministic, so the - /// compilation remains deterministic. - pub fn set_deterministic_prefixer(&mut self, prefixer: F) - where - F: Fn(&[u8]) -> String + Send + 'static, - { - let mut inner = self.inner_mut(); - inner.prefixer = Some(Box::new(prefixer)); - } - - pub(crate) fn inner(&self) -> std::sync::MutexGuard<'_, StaticlibEngineInner> { - self.inner.lock().unwrap() - } - - pub(crate) fn inner_mut(&self) -> std::sync::MutexGuard<'_, StaticlibEngineInner> { - self.inner.lock().unwrap() - } -} - -impl Engine for StaticlibEngine { - /// The target - fn target(&self) -> &Target { - &self.target - } - - /// Register a signature - fn register_signature(&self, func_type: &FunctionType) -> VMSharedSignatureIndex { - let compiler = self.inner(); - compiler.signatures().register(func_type) - } - - fn register_function_metadata(&self, func_data: VMCallerCheckedAnyfunc) -> VMFuncRef { - let compiler = self.inner(); - compiler.func_data().register(func_data) - } - - /// Lookup a signature - fn lookup_signature(&self, sig: VMSharedSignatureIndex) -> Option { - let compiler = self.inner(); - compiler.signatures().lookup(sig) - } - - /// Validates a WebAssembly module - fn validate(&self, binary: &[u8]) -> Result<(), CompileError> { - self.inner().validate(binary) - } - - /// Compile a WebAssembly binary - #[cfg(feature = "compiler")] - fn compile( - &self, - binary: &[u8], - tunables: &dyn Tunables, - ) -> Result, CompileError> { - Ok(Arc::new(StaticlibArtifact::new(self, binary, tunables)?)) - } - - /// Compile a WebAssembly binary (it will fail because the `compiler` flag is disabled). - #[cfg(not(feature = "compiler"))] - fn compile( - &self, - _binary: &[u8], - _tunables: &dyn Tunables, - ) -> Result, CompileError> { - Err(CompileError::Codegen( - "The `StaticlibEngine` is operating in headless mode, so it cannot compile a module." - .to_string(), - )) - } - - /// Deserializes a WebAssembly module (binary content of a static object file) - unsafe fn deserialize(&self, bytes: &[u8]) -> Result, DeserializeError> { - Ok(Arc::new(StaticlibArtifact::deserialize(self, bytes)?)) - } - - /// Deserializes a WebAssembly module from a path - /// - /// It should point to a static object file generated by this - /// engine. - unsafe fn deserialize_from_file( - &self, - file_ref: &Path, - ) -> Result, DeserializeError> { - let mut f = std::fs::File::open(file_ref)?; - let mut vec = vec![]; - f.read_to_end(&mut vec)?; - - self.deserialize(&vec[..]) - } - - fn id(&self) -> &EngineId { - &self.engine_id - } - - fn cloned(&self) -> Arc { - Arc::new(self.clone()) - } -} - -/// The inner contents of `StaticlibEngine` -pub struct StaticlibEngineInner { - /// The compiler - #[cfg(feature = "compiler")] - compiler: Option>, - - /// The WebAssembly features to use - #[cfg(feature = "compiler")] - features: Features, - - /// The signature registry is used mainly to operate with trampolines - /// performantly. - signatures: SignatureRegistry, - - /// The backing storage of `VMFuncRef`s. This centralized store ensures that 2 - /// functions with the same `VMCallerCheckedAnyfunc` will have the same `VMFuncRef`. - /// It also guarantees that the `VMFuncRef`s stay valid until the engine is dropped. - func_data: Arc, - - /// The prefixer returns the a String to prefix each of the - /// functions in the static object generated by the - /// `StaticlibEngine`, so we can assure no collisions. - prefixer: Option String + Send>>, -} - -impl StaticlibEngineInner { - /// Gets the compiler associated to this engine. - #[cfg(feature = "compiler")] - pub fn compiler(&self) -> Result<&dyn Compiler, CompileError> { - if self.compiler.is_none() { - return Err(CompileError::Codegen("The `StaticlibEngine` is operating in headless mode, so it can only execute already compiled Modules.".to_string())); - } - Ok(&**self - .compiler - .as_ref() - .expect("Can't get compiler reference")) - } - - #[cfg(feature = "compiler")] - pub(crate) fn get_prefix(&self, bytes: &[u8]) -> String { - if let Some(prefixer) = &self.prefixer { - prefixer(bytes) - } else { - "".to_string() - } - } - - #[cfg(feature = "compiler")] - pub(crate) fn features(&self) -> &Features { - &self.features - } - - /// Validate the module - #[cfg(feature = "compiler")] - pub fn validate(&self, data: &[u8]) -> Result<(), CompileError> { - self.compiler()?.validate_module(self.features(), data) - } - - /// Validate the module - #[cfg(not(feature = "compiler"))] - pub fn validate(&self, _data: &[u8]) -> Result<(), CompileError> { - Err(CompileError::Validate( - "The `StaticlibEngine` is not compiled with compiler support, which is required for validating".to_string(), - )) - } - - /// Shared signature registry. - pub fn signatures(&self) -> &SignatureRegistry { - &self.signatures - } - - /// Shared func metadata registry. - pub(crate) fn func_data(&self) -> &Arc { - &self.func_data - } -} diff --git a/lib/engine-staticlib/src/lib.rs b/lib/engine-staticlib/src/lib.rs deleted file mode 100644 index 199e1cf3248..00000000000 --- a/lib/engine-staticlib/src/lib.rs +++ /dev/null @@ -1,33 +0,0 @@ -//! Staticlib engine for Wasmer compilers. -//! -//! Given a compiler (such as `CraneliftCompiler` or `LLVMCompiler`) -//! it generates a static object file (`.o` file) and metadata which -//! can be used to access it from other programming languages static. - -#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] -#![warn(unused_import_braces)] -#![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))] -#![cfg_attr( - feature = "cargo-clippy", - warn( - clippy::float_arithmetic, - clippy::mut_mut, - clippy::nonminimal_bool, - clippy::map_unwrap_or, - clippy::print_stdout, - clippy::unicode_not_nfc, - clippy::use_self - ) -)] - -mod artifact; -mod builder; -mod engine; -mod serialize; - -pub use crate::artifact::StaticlibArtifact; -pub use crate::builder::Staticlib; -pub use crate::engine::StaticlibEngine; - -/// Version number of this crate. -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/lib/engine-staticlib/src/serialize.rs b/lib/engine-staticlib/src/serialize.rs deleted file mode 100644 index 34e8f87bf1a..00000000000 --- a/lib/engine-staticlib/src/serialize.rs +++ /dev/null @@ -1,91 +0,0 @@ -use serde::{Deserialize, Serialize}; -use wasmer_compiler::{CompileModuleInfo, SectionIndex, Symbol, SymbolRegistry}; -use wasmer_types::entity::{EntityRef, PrimaryMap}; -use wasmer_types::{FunctionIndex, LocalFunctionIndex, OwnedDataInitializer, SignatureIndex}; - -/// Serializable struct that represents the compiled metadata. -#[derive(Serialize, Deserialize, Debug)] -pub struct ModuleMetadata { - pub compile_info: CompileModuleInfo, - pub prefix: String, - pub data_initializers: Box<[OwnedDataInitializer]>, - // The function body lengths (used to find function by address) - pub function_body_lengths: PrimaryMap, - pub cpu_features: u64, -} - -pub struct ModuleMetadataSymbolRegistry { - pub prefix: String, -} - -impl ModuleMetadata { - pub fn split(&mut self) -> (&mut CompileModuleInfo, ModuleMetadataSymbolRegistry) { - let compile_info = &mut self.compile_info; - let symbol_registry = ModuleMetadataSymbolRegistry { - prefix: self.prefix.clone(), - }; - (compile_info, symbol_registry) - } - - pub fn get_symbol_registry(&self) -> ModuleMetadataSymbolRegistry { - ModuleMetadataSymbolRegistry { - prefix: self.prefix.clone(), - } - } -} - -impl SymbolRegistry for ModuleMetadataSymbolRegistry { - fn symbol_to_name(&self, symbol: Symbol) -> String { - match symbol { - Symbol::LocalFunction(index) => { - format!("wasmer_function_{}_{}", self.prefix, index.index()) - } - Symbol::Section(index) => format!("wasmer_section_{}_{}", self.prefix, index.index()), - Symbol::FunctionCallTrampoline(index) => { - format!( - "wasmer_trampoline_function_call_{}_{}", - self.prefix, - index.index() - ) - } - Symbol::DynamicFunctionTrampoline(index) => { - format!( - "wasmer_trampoline_dynamic_function_{}_{}", - self.prefix, - index.index() - ) - } - } - } - - fn name_to_symbol(&self, name: &str) -> Option { - if let Some(index) = name.strip_prefix(&format!("wasmer_function_{}_", self.prefix)) { - index - .parse::() - .ok() - .map(|index| Symbol::LocalFunction(LocalFunctionIndex::from_u32(index))) - } else if let Some(index) = name.strip_prefix(&format!("wasmer_section_{}_", self.prefix)) { - index - .parse::() - .ok() - .map(|index| Symbol::Section(SectionIndex::from_u32(index))) - } else if let Some(index) = - name.strip_prefix(&format!("wasmer_trampoline_function_call_{}_", self.prefix)) - { - index - .parse::() - .ok() - .map(|index| Symbol::FunctionCallTrampoline(SignatureIndex::from_u32(index))) - } else if let Some(index) = name.strip_prefix(&format!( - "wasmer_trampoline_dynamic_function_{}_", - self.prefix - )) { - index - .parse::() - .ok() - .map(|index| Symbol::DynamicFunctionTrampoline(FunctionIndex::from_u32(index))) - } else { - None - } - } -} diff --git a/lib/engine-universal/Cargo.toml b/lib/engine-universal/Cargo.toml deleted file mode 100644 index d78cc8cbc43..00000000000 --- a/lib/engine-universal/Cargo.toml +++ /dev/null @@ -1,44 +0,0 @@ -[package] -name = "wasmer-engine-universal" -version = "2.3.0" -description = "Wasmer Universal Engine" -categories = ["wasm"] -keywords = ["wasm", "webassembly", "engine", "universal"] -authors = ["Wasmer Engineering Team "] -repository = "https://github.com/wasmerio/wasmer" -license = "MIT OR Apache-2.0 WITH LLVM-exception " -readme = "README.md" -edition = "2018" - -[dependencies] -wasmer-engine-universal-artifact = { path = "../universal-artifact", version = "=2.3.0", features = [ - "compiler", -] } -wasmer-types = { path = "../types", version = "=2.3.0", features = [ - "enable-rkyv", -] } -wasmer-compiler = { path = "../compiler", version = "=2.3.0", features = [ - "translator", - "enable-rkyv", -] } -wasmer-vm = { path = "../vm", version = "=2.3.0", features = ["enable-rkyv"] } -wasmer-engine = { path = "../engine", version = "=2.3.0" } -# flexbuffers = { path = "../../../flatbuffers/rust/flexbuffers", version = "0.1.0" } -cfg-if = "1.0" -leb128 = "0.2" -rkyv = "0.7.20" -enumset = "1.0" - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -region = { version = "3.0" } - -[target.'cfg(target_os = "windows")'.dependencies] -winapi = { version = "0.3", features = ["winnt", "impl-default"] } - -[features] -# Enable the `compiler` feature if you want the engine to compile -# and not be only on headless mode. -compiler = ["wasmer-compiler/translator"] - -[badges] -maintenance = { status = "actively-developed" } diff --git a/lib/engine-universal/README.md b/lib/engine-universal/README.md deleted file mode 100644 index 93d9ac321f5..00000000000 --- a/lib/engine-universal/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# `wasmer-engine-universal` [![Build Status](https://github.com/wasmerio/wasmer/workflows/build/badge.svg?style=flat-square)](https://github.com/wasmerio/wasmer/actions?query=workflow%3Abuild) [![Join Wasmer Slack](https://img.shields.io/static/v1?label=Slack&message=join%20chat&color=brighgreen&style=flat-square)](https://slack.wasmer.io) [![MIT License](https://img.shields.io/github/license/wasmerio/wasmer.svg?style=flat-square)](https://github.com/wasmerio/wasmer/blob/master/LICENSE) - -The Wasmer Universal engine is usable with any compiler implementation based -on [`wasmer-compiler`]. After the compiler process the result, the Universal -pushes it into memory and links its contents so it can be usable by -the [`wasmer`] API. - -*Note: you can find a [full working example using the Universal engine -here][example].* - -### Acknowledgments - -This project borrowed some of the code of the code memory and unwind -tables from the [`wasmtime-jit`], the code since then has evolved -significantly. - -Please check [Wasmer `ATTRIBUTIONS`] to further see licenses and other -attributions of the project. - - -[`wasmer-compiler`]: https://github.com/wasmerio/wasmer/tree/master/lib/compiler -[`wasmer`]: https://github.com/wasmerio/wasmer/tree/master/lib/api -[example]: https://github.com/wasmerio/wasmer/blob/master/examples/engine_universal.rs -[`wasmtime-jit`]: https://crates.io/crates/wasmtime-jit -[Wasmer `ATTRIBUTIONS`]: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md diff --git a/lib/engine-universal/src/lib.rs b/lib/engine-universal/src/lib.rs deleted file mode 100644 index 68afde89054..00000000000 --- a/lib/engine-universal/src/lib.rs +++ /dev/null @@ -1,40 +0,0 @@ -//! Universal backend for Wasmer compilers. -//! -//! Given a compiler (such as `CraneliftCompiler` or `LLVMCompiler`) -//! it generates the compiled machine code, and publishes it into -//! memory so it can be used externally. - -#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] -#![warn(unused_import_braces)] -#![cfg_attr( - feature = "cargo-clippy", - allow(clippy::new_without_default, clippy::new_without_default) -)] -#![cfg_attr( - feature = "cargo-clippy", - warn( - clippy::float_arithmetic, - clippy::mut_mut, - clippy::nonminimal_bool, - clippy::map_unwrap_or, - clippy::print_stdout, - clippy::unicode_not_nfc, - clippy::use_self - ) -)] - -mod artifact; -mod builder; -mod code_memory; -mod engine; -mod link; -mod unwind; - -pub use crate::artifact::UniversalArtifact; -pub use crate::builder::Universal; -pub use crate::code_memory::CodeMemory; -pub use crate::engine::UniversalEngine; -pub use crate::link::link_module; - -/// Version number of this crate. -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/lib/engine/Cargo.toml b/lib/engine/Cargo.toml deleted file mode 100644 index 03c51bf7bc3..00000000000 --- a/lib/engine/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "wasmer-engine" -version = "2.3.0" -description = "Wasmer Engine abstraction" -categories = ["wasm"] -keywords = ["wasm", "webassembly", "engine"] -authors = ["Wasmer Engineering Team "] -repository = "https://github.com/wasmerio/wasmer" -license = "MIT OR Apache-2.0 WITH LLVM-exception " -readme = "README.md" -edition = "2018" - -[dependencies] -wasmer-types = { path = "../types", version = "=2.3.0" } -wasmer-compiler = { path = "../compiler", version = "=2.3.0" } -wasmer-artifact = { path = "../artifact", version = "=2.3.0" } -target-lexicon = { version = "0.12.2", default-features = false } -# flexbuffers = { path = "../../../flatbuffers/rust/flexbuffers", version = "0.1.0" } -backtrace = "0.3" -rustc-demangle = "0.1" -memmap2 = "0.5" -more-asserts = "0.2" -thiserror = "1.0" -serde = { version = "1.0", features = ["derive", "rc"] } -serde_bytes = { version = "0.11" } -lazy_static = "1.4" -enumset = "1.0" - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -wasmer-vm = { path = "../vm", version = "=2.3.0" } - -[badges] -maintenance = { status = "actively-developed" } diff --git a/lib/engine/README.md b/lib/engine/README.md deleted file mode 100644 index c4de85c25dc..00000000000 --- a/lib/engine/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# `wasmer-engine` [![Build Status](https://github.com/wasmerio/wasmer/workflows/build/badge.svg?style=flat-square)](https://github.com/wasmerio/wasmer/actions?query=workflow%3Abuild) [![Join Wasmer Slack](https://img.shields.io/static/v1?label=Slack&message=join%20chat&color=brighgreen&style=flat-square)](https://slack.wasmer.io) [![MIT License](https://img.shields.io/github/license/wasmerio/wasmer.svg?style=flat-square)](https://github.com/wasmerio/wasmer/blob/master/LICENSE) - -This crate is the general abstraction for creating Engines in Wasmer. - -Wasmer Engines are mainly responsible for two things: -* Transform the compilation code (from any Wasmer Compiler) to - **create** an `Artifact`, -* **Load** an`Artifact` so it can be used by the user (normally, - pushing the code into executable memory and so on). - -It currently has three implementations: - -1. Universal with [`wasmer-engine-universal`], -2. Native with [`wasmer-engine-dylib`], -3. Object with [`wasmer-engine-staticlib`]. - -## Example Implementation - -Please check [`wasmer-engine-dummy`] for an example implementation for -an `Engine`. - -### Acknowledgments - -This project borrowed some of the code of the trap implementation from -the [`wasmtime-api`], the code since then has evolved significantly. - -Please check [Wasmer `ATTRIBUTIONS`] to further see licenses and other -attributions of the project. - - -[`wasmer-engine-universal`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-universal -[`wasmer-engine-dylib`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-dylib -[`wasmer-engine-staticlib`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-staticlib -[`wasmer-engine-dummy`]: https://github.com/wasmerio/wasmer/tree/master/tests/lib/engine-dummy -[`wasmtime-api`]: https://crates.io/crates/wasmtime -[Wasmer `ATTRIBUTIONS`]: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md diff --git a/lib/engine/src/lib.rs b/lib/engine/src/lib.rs deleted file mode 100644 index dd6c58e14f8..00000000000 --- a/lib/engine/src/lib.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! Generic Engine abstraction for Wasmer Engines. - -#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] -#![warn(unused_import_braces)] -#![cfg_attr( - feature = "cargo-clippy", - allow( - clippy::new_without_default, - clippy::upper_case_acronyms, - clippy::new_without_default - ) -)] -#![cfg_attr( - feature = "cargo-clippy", - warn( - clippy::float_arithmetic, - clippy::mut_mut, - clippy::nonminimal_bool, - clippy::map_unwrap_or, - clippy::print_stdout, - clippy::unicode_not_nfc, - clippy::use_self - ) -)] - -mod artifact; -mod engine; -mod error; -mod export; -mod resolver; -mod trap; -mod tunables; - -pub use crate::artifact::Artifact; -pub use crate::engine::{Engine, EngineId}; -pub use crate::error::{InstantiationError, LinkError}; -pub use crate::export::{Export, ExportFunction, ExportFunctionMetadata}; -pub use crate::resolver::resolve_imports; -pub use crate::trap::*; -pub use crate::tunables::Tunables; -pub use wasmer_artifact::{ArtifactCreate, MetadataHeader}; -pub use wasmer_artifact::{DeserializeError, ImportError, SerializeError}; - -/// Version number of this crate. -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/lib/middlewares/src/metering.rs b/lib/middlewares/src/metering.rs index 6ae7e6a639e..ba9cff4576b 100644 --- a/lib/middlewares/src/metering.rs +++ b/lib/middlewares/src/metering.rs @@ -383,7 +383,7 @@ mod tests { let metering = Arc::new(Metering::new(10, cost_function)); let mut compiler_config = Cranelift::default(); compiler_config.push_middleware(metering); - let store = Store::new(&Universal::new(compiler_config).engine()); + let store = Store::new_with_engine(&Universal::new(compiler_config).engine()); let module = Module::new(&store, bytecode()).unwrap(); // Instantiate @@ -428,7 +428,7 @@ mod tests { let metering = Arc::new(Metering::new(10, cost_function)); let mut compiler_config = Cranelift::default(); compiler_config.push_middleware(metering); - let store = Store::new(&Universal::new(compiler_config).engine()); + let store = Store::new_with_engine(&Universal::new(compiler_config).engine()); let module = Module::new(&store, bytecode()).unwrap(); // Instantiate diff --git a/lib/object/src/module.rs b/lib/object/src/module.rs index 13444234423..8c3ef2923c9 100644 --- a/lib/object/src/module.rs +++ b/lib/object/src/module.rs @@ -6,12 +6,12 @@ use object::{ elf, macho, RelocationEncoding, RelocationKind, SectionKind, SymbolFlags, SymbolKind, SymbolScope, }; -use wasmer_compiler::{ - Architecture, BinaryFormat, Compilation, CustomSectionProtection, Endianness, - RelocationKind as Reloc, RelocationTarget, SectionIndex, Symbol, SymbolRegistry, Triple, -}; +use wasmer_compiler::{Architecture, BinaryFormat, Endianness, Symbol, SymbolRegistry, Triple}; use wasmer_types::entity::PrimaryMap; use wasmer_types::LocalFunctionIndex; +use wasmer_types::{ + Compilation, CustomSectionProtection, RelocationKind as Reloc, RelocationTarget, SectionIndex, +}; const DWARF_SECTION_NAME: &[u8] = b".eh_frame"; @@ -110,7 +110,8 @@ pub fn emit_data( /// # Usage /// /// ```rust -/// # use wasmer_compiler::{Compilation, SymbolRegistry, Triple}; +/// # use wasmer_compiler::{SymbolRegistry, Triple}; +/// # use wasmer_types::Compilation; /// # use wasmer_object::ObjectError; /// use wasmer_object::{get_object_for_target, emit_compilation}; /// diff --git a/lib/types/Cargo.toml b/lib/types/Cargo.toml index a076c019613..3c8fda7de0d 100644 --- a/lib/types/Cargo.toml +++ b/lib/types/Cargo.toml @@ -12,18 +12,18 @@ edition = "2018" [dependencies] serde = { version = "1.0", features = ["derive", "rc"], optional = true, default-features = false } +serde_bytes = { version = "0.11", optional = true } thiserror = "1.0" more-asserts = "0.2" indexmap = { version = "1.6", features = ["serde-1"] } -rkyv = { version = "0.7.20", optional = true } +rkyv = { version = "0.7.38", features = ["indexmap"] } enum-iterator = "0.7.0" [features] -default = ["std", "enable-serde", "enable-rkyv"] +default = ["std", "enable-serde"] std = [] core = [] -enable-rkyv = ["rkyv"] -enable-serde = ["serde", "serde/std"] +enable-serde = ["serde", "serde/std", "serde_bytes"] # experimental / in-development features experimental-reference-types-extern-ref = [] diff --git a/lib/types/src/archives.rs b/lib/types/src/archives.rs deleted file mode 100644 index f3887271d3c..00000000000 --- a/lib/types/src/archives.rs +++ /dev/null @@ -1,29 +0,0 @@ -#[cfg(feature = "core")] -use core::hash::Hash; -use indexmap::IndexMap; -use rkyv::{Archive, Deserialize, Serialize}; -#[cfg(feature = "std")] -use std::hash::Hash; - -#[derive(Serialize, Deserialize, Archive)] -/// Rkyv Archivable IndexMap -pub struct ArchivableIndexMap { - entries: Vec<(K, V)>, -} - -impl From> - for ArchivableIndexMap -{ - fn from(it: IndexMap) -> Self { - let entries = it.into_iter().collect(); - Self { entries } - } -} - -impl From> - for IndexMap -{ - fn from(other: ArchivableIndexMap) -> Self { - other.entries.into_iter().collect() - } -} diff --git a/lib/compiler/src/address_map.rs b/lib/types/src/compilation/address_map.rs similarity index 79% rename from lib/compiler/src/address_map.rs rename to lib/types/src/compilation/address_map.rs index 5580022f2fb..6d7c1d973d9 100644 --- a/lib/compiler/src/address_map.rs +++ b/lib/types/src/compilation/address_map.rs @@ -1,20 +1,15 @@ //! Data structures to provide transformation of the source // addresses of a WebAssembly module into the native code. +use super::sourceloc::SourceLoc; use crate::lib::std::vec::Vec; -use crate::sourceloc::SourceLoc; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; /// Single source location to generated address mapping. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)] pub struct InstructionAddressMap { /// Original source location. pub srcloc: SourceLoc, @@ -28,11 +23,7 @@ pub struct InstructionAddressMap { /// Function and its instructions addresses mappings. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Debug, Clone, PartialEq, Eq, Default)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq, Default)] pub struct FunctionAddressMap { /// Instructions maps. /// The array is sorted by the InstructionAddressMap::code_offset field. diff --git a/lib/compiler/src/function.rs b/lib/types/src/compilation/function.rs similarity index 90% rename from lib/compiler/src/function.rs rename to lib/types/src/compilation/function.rs index 3f85f161a67..e0560e0bec6 100644 --- a/lib/compiler/src/function.rs +++ b/lib/types/src/compilation/function.rs @@ -4,27 +4,23 @@ //! A `Compilation` contains the compiled function bodies for a WebAssembly //! module (`CompiledFunction`). +use super::trap::TrapInformation; +use crate::entity::PrimaryMap; use crate::lib::std::vec::Vec; -use crate::section::{CustomSection, SectionIndex}; -use crate::trap::TrapInformation; -use crate::{CompiledFunctionUnwindInfo, FunctionAddressMap, Relocation}; -#[cfg(feature = "enable-rkyv")] +use crate::{CompiledFunctionUnwindInfo, FunctionAddressMap}; +use crate::{ + CustomSection, FunctionIndex, LocalFunctionIndex, Relocation, SectionIndex, SignatureIndex, +}; use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; -use wasmer_types::entity::PrimaryMap; -use wasmer_types::{FunctionIndex, LocalFunctionIndex, SignatureIndex}; /// The frame info for a Compiled function. /// /// This structure is only used for reconstructing /// the frame information after a `Trap`. #[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Debug, Clone, PartialEq, Eq, Default)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq, Default)] pub struct CompiledFunctionFrameInfo { /// The traps (in the function body). /// @@ -37,11 +33,7 @@ pub struct CompiledFunctionFrameInfo { /// The function body. #[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)] pub struct FunctionBody { /// The function body bytes. #[cfg_attr(feature = "enable-serde", serde(with = "serde_bytes"))] @@ -57,11 +49,7 @@ pub struct FunctionBody { /// (function bytecode body, relocations, traps, jump tables /// and unwind information). #[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)] pub struct CompiledFunction { /// The function body. pub body: FunctionBody, @@ -86,11 +74,7 @@ pub type CustomSections = PrimaryMap; /// In the future this structure may also hold other information useful /// for debugging. #[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, PartialEq, Eq, Clone)] pub struct Dwarf { /// The section index in the [`Compilation`] that corresponds to the exception frames. /// [Learn @@ -250,6 +234,7 @@ impl<'a> IntoIterator for &'a Compilation { } } +/// `Functions` iterator. pub struct Iter<'a> { iterator: <&'a Functions as IntoIterator>::IntoIter, } diff --git a/lib/types/src/compilation/mod.rs b/lib/types/src/compilation/mod.rs new file mode 100644 index 00000000000..2c181528c4f --- /dev/null +++ b/lib/types/src/compilation/mod.rs @@ -0,0 +1,10 @@ +//! Types for compilation. + +pub mod address_map; +pub mod function; +pub mod module; +pub mod relocation; +pub mod section; +pub mod sourceloc; +pub mod trap; +pub mod unwind; diff --git a/lib/compiler/src/module.rs b/lib/types/src/compilation/module.rs similarity index 77% rename from lib/compiler/src/module.rs rename to lib/types/src/compilation/module.rs index dc6fdd9d7bc..9fceddce409 100644 --- a/lib/compiler/src/module.rs +++ b/lib/types/src/compilation/module.rs @@ -1,22 +1,18 @@ +//! Types for modules. +use crate::entity::PrimaryMap; use crate::lib::std::sync::Arc; -#[cfg(feature = "enable-rkyv")] +use crate::{Features, MemoryIndex, MemoryStyle, ModuleInfo, TableIndex, TableStyle}; use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; -use wasmer_types::entity::PrimaryMap; -use wasmer_types::{Features, MemoryIndex, MemoryStyle, ModuleInfo, TableIndex, TableStyle}; /// The required info for compiling a module. /// /// This differs from [`ModuleInfo`] because it have extra info only /// possible after translation (such as the features used for compiling, /// or the `MemoryStyle` and `TableStyle`). -#[derive(Debug, PartialEq, Eq)] #[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(Debug, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive)] pub struct CompileModuleInfo { /// The features used for compiling the module pub features: Features, diff --git a/lib/compiler/src/relocation.rs b/lib/types/src/compilation/relocation.rs similarity index 91% rename from lib/compiler/src/relocation.rs rename to lib/types/src/compilation/relocation.rs index 6e106642076..6286e455727 100644 --- a/lib/compiler/src/relocation.rs +++ b/lib/types/src/compilation/relocation.rs @@ -9,24 +9,19 @@ //! the generated machine code, so a given frontend (JIT or native) can //! do the corresponding work to run it. +use super::section::SectionIndex; +use crate::entity::PrimaryMap; use crate::lib::std::fmt; use crate::lib::std::vec::Vec; -use crate::section::SectionIndex; use crate::{Addend, CodeOffset}; -#[cfg(feature = "enable-rkyv")] +use crate::{LibCall, LocalFunctionIndex}; use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; -use wasmer_types::entity::PrimaryMap; -use wasmer_types::{LibCall, LocalFunctionIndex}; /// Relocation kinds for every ISA. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Copy, Clone, Debug, PartialEq, Eq)] pub enum RelocationKind { /// absolute 4-byte Abs4, @@ -75,11 +70,7 @@ impl fmt::Display for RelocationKind { /// A record of a relocation to perform. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)] pub struct Relocation { /// The relocation kind. pub kind: RelocationKind, @@ -93,11 +84,7 @@ pub struct Relocation { /// Destination function. Can be either user function or some special one, like `memory.grow`. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Copy, Clone, PartialEq, Eq)] pub enum RelocationTarget { /// A relocation to a function defined locally in the wasm (not an imported one). LocalFunc(LocalFunctionIndex), diff --git a/lib/compiler/src/section.rs b/lib/types/src/compilation/section.rs similarity index 76% rename from lib/compiler/src/section.rs rename to lib/types/src/compilation/section.rs index b175bbfdc3d..09ea1da72aa 100644 --- a/lib/compiler/src/section.rs +++ b/lib/types/src/compilation/section.rs @@ -5,41 +5,40 @@ //! to emit a custom relocation: `RelocationTarget::CustomSection`, so //! it can be patched later by the engine (native or JIT). +use super::relocation::Relocation; +use crate::entity::entity_impl; use crate::lib::std::vec::Vec; -use crate::Relocation; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; -use wasmer_types::entity::entity_impl; /// Index type of a Section defined inside a WebAssembly `Compilation`. -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + RkyvSerialize, + RkyvDeserialize, + Archive, + Copy, + Clone, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Debug, )] -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub struct SectionIndex(u32); entity_impl!(SectionIndex); -#[cfg(feature = "enable-rkyv")] entity_impl!(ArchivedSectionIndex); /// Custom section Protection. /// /// Determines how a custom section may be used. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)] pub enum CustomSectionProtection { /// A custom section with read permission. Read, @@ -53,11 +52,7 @@ pub enum CustomSectionProtection { /// This is used so compilers can store arbitrary information /// in the emitted module. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)] pub struct CustomSection { /// Memory protection that applies to this section. pub protection: CustomSectionProtection, @@ -76,11 +71,7 @@ pub struct CustomSection { /// The bytes in the section. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Debug, Clone, PartialEq, Eq, Default)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq, Default)] pub struct SectionBody(#[cfg_attr(feature = "enable-serde", serde(with = "serde_bytes"))] Vec); impl SectionBody { diff --git a/lib/compiler/src/sourceloc.rs b/lib/types/src/compilation/sourceloc.rs similarity index 93% rename from lib/compiler/src/sourceloc.rs rename to lib/types/src/compilation/sourceloc.rs index dfd6d8872d5..7117639871a 100644 --- a/lib/compiler/src/sourceloc.rs +++ b/lib/types/src/compilation/sourceloc.rs @@ -8,7 +8,6 @@ //! and tracing errors. use crate::lib::std::fmt; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -22,10 +21,7 @@ use serde::{Deserialize, Serialize}; derive(Serialize, Deserialize), serde(transparent) )] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive)] #[repr(transparent)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SourceLoc(u32); diff --git a/lib/compiler/src/trap.rs b/lib/types/src/compilation/trap.rs similarity index 72% rename from lib/compiler/src/trap.rs rename to lib/types/src/compilation/trap.rs index 24a2b147a05..8398413160a 100644 --- a/lib/compiler/src/trap.rs +++ b/lib/types/src/compilation/trap.rs @@ -1,17 +1,13 @@ +//! Types for traps. use crate::CodeOffset; -#[cfg(feature = "enable-rkyv")] +use crate::TrapCode; use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; -use wasmer_types::TrapCode; /// Information about trap. #[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Clone, Debug, PartialEq, Eq)] pub struct TrapInformation { /// The offset of the trapping instruction in native code. It is relative to the beginning of the function. pub code_offset: CodeOffset, diff --git a/lib/compiler/src/unwind.rs b/lib/types/src/compilation/unwind.rs similarity index 86% rename from lib/compiler/src/unwind.rs rename to lib/types/src/compilation/unwind.rs index 41d0ea2f019..249b173c78b 100644 --- a/lib/compiler/src/unwind.rs +++ b/lib/types/src/compilation/unwind.rs @@ -6,7 +6,6 @@ //! //! [Learn more](https://en.wikipedia.org/wiki/Call_stack). use crate::lib::std::vec::Vec; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -19,11 +18,7 @@ use serde::{Deserialize, Serialize}; /// /// [unwind info]: https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64?view=vs-2019 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)] pub enum CompiledFunctionUnwindInfo { /// Windows UNWIND_INFO. WindowsX64(Vec), diff --git a/lib/types/src/entity/primary_map.rs b/lib/types/src/entity/primary_map.rs index 5a844732976..e1c1927fd3e 100644 --- a/lib/types/src/entity/primary_map.rs +++ b/lib/types/src/entity/primary_map.rs @@ -12,7 +12,6 @@ use crate::lib::std::marker::PhantomData; use crate::lib::std::ops::{Index, IndexMut}; use crate::lib::std::slice; use crate::lib::std::vec::Vec; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -34,10 +33,7 @@ use serde::{Deserialize, Serialize}; /// `into_boxed_slice`. #[derive(Debug, Clone, Hash, PartialEq, Eq)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive)] pub struct PrimaryMap where K: EntityRef, diff --git a/lib/types/src/entity/secondary_map.rs b/lib/types/src/entity/secondary_map.rs index 584ee34c269..f9df40abf01 100644 --- a/lib/types/src/entity/secondary_map.rs +++ b/lib/types/src/entity/secondary_map.rs @@ -11,7 +11,6 @@ use crate::lib::std::marker::PhantomData; use crate::lib::std::ops::{Index, IndexMut}; use crate::lib::std::slice; use crate::lib::std::vec::Vec; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{ @@ -28,11 +27,7 @@ use serde::{ /// /// The map does not track if an entry for a key has been inserted or not. Instead it behaves as if /// all keys have a default entry from the beginning. -#[derive(Debug, Clone)] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(Debug, Clone, RkyvSerialize, RkyvDeserialize, Archive)] pub struct SecondaryMap where K: EntityRef, diff --git a/lib/compiler/src/error.rs b/lib/types/src/error.rs similarity index 72% rename from lib/compiler/src/error.rs rename to lib/types/src/error.rs index cf107ad6363..115cb1ae6c1 100644 --- a/lib/compiler/src/error.rs +++ b/lib/types/src/error.rs @@ -1,7 +1,71 @@ -use crate::lib::std::string::String; -#[cfg(feature = "std")] +//! The WebAssembly possible errors +use crate::ExternType; +use std::io; use thiserror::Error; +/// The Serialize error can occur when serializing a +/// compiled Module into a binary. +#[derive(Error, Debug)] +pub enum SerializeError { + /// An IO error + #[error(transparent)] + Io(#[from] io::Error), + /// A generic serialization error + #[error("{0}")] + Generic(String), +} + +/// The Deserialize error can occur when loading a +/// compiled Module from a binary. +#[derive(Error, Debug)] +pub enum DeserializeError { + /// An IO error + #[error(transparent)] + Io(#[from] io::Error), + /// A generic deserialization error + #[error("{0}")] + Generic(String), + /// Incompatible serialized binary + #[error("incompatible binary: {0}")] + Incompatible(String), + /// The provided binary is corrupted + #[error("corrupted binary: {0}")] + CorruptedBinary(String), + /// The binary was valid, but we got an error when + /// trying to allocate the required resources. + #[error(transparent)] + Compiler(CompileError), +} + +/// An ImportError. +/// +/// Note: this error is not standard to WebAssembly, but it's +/// useful to determine the import issue on the API side. +#[derive(Error, Debug)] +pub enum ImportError { + /// Incompatible Import Type. + /// This error occurs when the import types mismatch. + #[error("incompatible import type. Expected {0:?} but received {1:?}")] + IncompatibleType(ExternType, ExternType), + + /// Unknown Import. + /// This error occurs when an import was expected but not provided. + #[error("unknown import. Expected {0:?}")] + UnknownImport(ExternType), +} + +/// An error while preinstantiating a module. +/// +#[derive(Error, Debug)] +pub enum PreInstantiationError { + /// The module was compiled with a CPU feature that is not available on + /// the current host. + #[error("module compiled with CPU feature that is missing from host")] + CpuFeature(String), +} + +use crate::lib::std::string::String; + // Compilation Errors // // If `std` feature is enable, we can't use `thiserror` until diff --git a/lib/types/src/features.rs b/lib/types/src/features.rs index 32449e42985..99a419a6025 100644 --- a/lib/types/src/features.rs +++ b/lib/types/src/features.rs @@ -1,4 +1,3 @@ -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -9,10 +8,7 @@ use serde::{Deserialize, Serialize}; /// [WebAssembly proposal]: https://github.com/WebAssembly/proposals #[derive(Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive)] pub struct Features { /// Threads proposal should be enabled pub threads: bool, diff --git a/lib/types/src/indexes.rs b/lib/types/src/indexes.rs index 8522410a202..ac2a2bc6b40 100644 --- a/lib/types/src/indexes.rs +++ b/lib/types/src/indexes.rs @@ -1,25 +1,28 @@ //! Helper functions and structures for the translation. use crate::entity::entity_impl; use core::u32; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; /// Index type of a function defined locally inside the WebAssembly module. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Debug, + RkyvSerialize, + RkyvDeserialize, + Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub struct LocalFunctionIndex(u32); entity_impl!(LocalFunctionIndex); -#[cfg(feature = "enable-rkyv")] entity_impl!(ArchivedLocalFunctionIndex); /// Index type of a table defined locally inside the WebAssembly module. @@ -35,160 +38,191 @@ pub struct LocalMemoryIndex(u32); entity_impl!(LocalMemoryIndex); /// Index type of a global defined locally inside the WebAssembly module. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Debug, + RkyvSerialize, + RkyvDeserialize, + Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub struct LocalGlobalIndex(u32); entity_impl!(LocalGlobalIndex); -#[cfg(feature = "enable-rkyv")] entity_impl!(ArchivedLocalGlobalIndex); /// Index type of a function (imported or local) inside the WebAssembly module. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Debug, + RkyvSerialize, + RkyvDeserialize, + Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub struct FunctionIndex(u32); entity_impl!(FunctionIndex); -#[cfg(feature = "enable-rkyv")] entity_impl!(ArchivedFunctionIndex); /// Index type of a table (imported or local) inside the WebAssembly module. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Debug, + RkyvSerialize, + RkyvDeserialize, + Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub struct TableIndex(u32); entity_impl!(TableIndex); -#[cfg(feature = "enable-rkyv")] entity_impl!(ArchivedTableIndex); /// Index type of a global variable (imported or local) inside the WebAssembly module. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Debug, + RkyvSerialize, + RkyvDeserialize, + Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub struct GlobalIndex(u32); entity_impl!(GlobalIndex); -#[cfg(feature = "enable-rkyv")] entity_impl!(ArchivedGlobalIndex); /// Index type of a linear memory (imported or local) inside the WebAssembly module. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Debug, + RkyvSerialize, + RkyvDeserialize, + Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub struct MemoryIndex(u32); entity_impl!(MemoryIndex); -#[cfg(feature = "enable-rkyv")] entity_impl!(ArchivedMemoryIndex); /// Index type of a signature (imported or local) inside the WebAssembly module. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Debug, + RkyvSerialize, + RkyvDeserialize, + Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub struct SignatureIndex(u32); entity_impl!(SignatureIndex); -#[cfg(feature = "enable-rkyv")] entity_impl!(ArchivedSignatureIndex); /// Index type of a passive data segment inside the WebAssembly module. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Debug, + RkyvSerialize, + RkyvDeserialize, + Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub struct DataIndex(u32); entity_impl!(DataIndex); -#[cfg(feature = "enable-rkyv")] entity_impl!(ArchivedDataIndex); /// Index type of a passive element segment inside the WebAssembly module. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Debug, + RkyvSerialize, + RkyvDeserialize, + Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub struct ElemIndex(u32); entity_impl!(ElemIndex); -#[cfg(feature = "enable-rkyv")] entity_impl!(ArchivedElemIndex); /// Index type of a custom section inside a WebAssembly module. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Debug, + RkyvSerialize, + RkyvDeserialize, + Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub struct CustomSectionIndex(u32); entity_impl!(CustomSectionIndex); -#[cfg(feature = "enable-rkyv")] entity_impl!(ArchivedCustomSectionIndex); /// An entity to export. -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, RkyvSerialize, RkyvDeserialize, Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub enum ExportIndex { /// Function export. Function(FunctionIndex), @@ -201,16 +235,11 @@ pub enum ExportIndex { } /// An entity to import. -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] -#[cfg_attr( - feature = "enable-rkyv", - archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)) +#[derive( + Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, RkyvSerialize, RkyvDeserialize, Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))] pub enum ImportIndex { /// Function import. Function(FunctionIndex), diff --git a/lib/types/src/initializers.rs b/lib/types/src/initializers.rs index 8316daed53e..a34deaf13bd 100644 --- a/lib/types/src/initializers.rs +++ b/lib/types/src/initializers.rs @@ -1,17 +1,12 @@ use crate::indexes::{FunctionIndex, GlobalIndex, MemoryIndex, TableIndex}; use crate::lib::std::boxed::Box; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; /// A WebAssembly table initializer. -#[derive(Clone, Debug, Hash, PartialEq, Eq)] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(Clone, Debug, Hash, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct TableInitializer { /// The index of a table to initialize. @@ -26,12 +21,8 @@ pub struct TableInitializer { /// A memory index and offset within that memory where a data initialization /// should be performed. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] pub struct DataInitializerLocation { /// The index of the memory to initialize. pub memory_index: MemoryIndex, @@ -56,12 +47,8 @@ pub struct DataInitializer<'data> { /// As `DataInitializer` but owning the data rather than /// holding a reference to it -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] pub struct OwnedDataInitializer { /// The location where the initialization is to be performed. pub location: DataInitializerLocation, diff --git a/lib/types/src/lib.rs b/lib/types/src/lib.rs index b001ab0a17c..51cf8193e94 100644 --- a/lib/types/src/lib.rs +++ b/lib/types/src/lib.rs @@ -53,8 +53,8 @@ pub mod lib { } } -#[cfg(feature = "enable-rkyv")] -mod archives; +pub mod compilation; +pub mod error; mod extern_ref; mod features; mod indexes; @@ -71,6 +71,11 @@ mod utils; mod values; mod vmoffsets; +pub use error::{ + CompileError, DeserializeError, ImportError, MiddlewareError, ParseCpuFeatureError, + PreInstantiationError, SerializeError, WasmError, WasmResult, +}; + /// The entity module, with common helpers for Rust structures pub mod entity; pub use crate::extern_ref::{ExternRef, VMExternRef}; @@ -95,9 +100,6 @@ pub use types::{ Mutability, TableType, Type, V128, }; -#[cfg(feature = "enable-rkyv")] -pub use archives::ArchivableIndexMap; - pub use crate::libcalls::LibCall; pub use crate::memory::MemoryStyle; pub use crate::table::TableStyle; @@ -106,5 +108,28 @@ pub use crate::vmoffsets::{TargetSharedSignatureIndex, VMBuiltinFunctionIndex, V pub use crate::utils::is_wasm; +pub use crate::compilation::relocation::{ + Relocation, RelocationKind, RelocationTarget, Relocations, +}; +pub use crate::compilation::section::{ + CustomSection, CustomSectionProtection, SectionBody, SectionIndex, +}; + +pub use crate::compilation::address_map::{FunctionAddressMap, InstructionAddressMap}; +pub use crate::compilation::function::{ + Compilation, CompiledFunction, CompiledFunctionFrameInfo, CustomSections, Dwarf, FunctionBody, + Functions, +}; +pub use crate::compilation::module::CompileModuleInfo; +pub use crate::compilation::sourceloc::SourceLoc; +pub use crate::compilation::trap::TrapInformation; +pub use crate::compilation::unwind::CompiledFunctionUnwindInfo; + +/// Offset in bytes from the beginning of the function. +pub type CodeOffset = u32; + +/// Addend to add to the symbol value. +pub type Addend = i64; + /// Version number of this crate. pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/lib/types/src/libcalls.rs b/lib/types/src/libcalls.rs index 1a9577e7b63..774a2271908 100644 --- a/lib/types/src/libcalls.rs +++ b/lib/types/src/libcalls.rs @@ -1,5 +1,4 @@ use enum_iterator::IntoEnumIterator; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -8,12 +7,19 @@ use std::fmt; /// The name of a runtime library routine. /// /// This list is likely to grow over time. -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) +#[derive( + Copy, + Clone, + Debug, + PartialEq, + Eq, + Hash, + IntoEnumIterator, + RkyvSerialize, + RkyvDeserialize, + Archive, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, IntoEnumIterator)] pub enum LibCall { /// ceil.f32 CeilF32, diff --git a/lib/types/src/memory.rs b/lib/types/src/memory.rs index b49fb71a398..a842abda4e9 100644 --- a/lib/types/src/memory.rs +++ b/lib/types/src/memory.rs @@ -1,5 +1,4 @@ use crate::{Pages, ValueType}; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -8,11 +7,7 @@ use std::iter::Sum; use std::ops::{Add, AddAssign}; /// Implementation styles for WebAssembly linear memory. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, RkyvSerialize, RkyvDeserialize, Archive)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub enum MemoryStyle { /// The actual memory can be resized and moved. diff --git a/lib/types/src/module.rs b/lib/types/src/module.rs index 6779a53eac7..8c4ef1862af 100644 --- a/lib/types/src/module.rs +++ b/lib/types/src/module.rs @@ -5,8 +5,6 @@ //! `wasmer::Module`. use crate::entity::{EntityRef, PrimaryMap}; -#[cfg(feature = "enable-rkyv")] -use crate::ArchivableIndexMap; use crate::{ CustomSectionIndex, DataIndex, ElemIndex, ExportIndex, ExportType, ExternType, FunctionIndex, FunctionType, GlobalIndex, GlobalInit, GlobalType, ImportIndex, ImportType, LocalFunctionIndex, @@ -14,7 +12,6 @@ use crate::{ TableIndex, TableInitializer, TableType, }; use indexmap::IndexMap; -#[cfg(feature = "enable-rkyv")] use rkyv::{ de::SharedDeserializeRegistry, ser::ScratchSpace, ser::Serializer, ser::SharedSerializeRegistry, Archive, Archived, Deserialize as RkyvDeserialize, Fallible, @@ -22,7 +19,6 @@ use rkyv::{ }; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; -#[cfg(feature = "enable-rkyv")] use std::collections::BTreeMap; use std::collections::HashMap; use std::fmt; @@ -30,11 +26,7 @@ use std::iter::ExactSizeIterator; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use std::sync::Arc; -#[derive(Debug, Clone)] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(Debug, Clone, RkyvSerialize, RkyvDeserialize, Archive)] pub struct ModuleId { id: usize, } @@ -134,12 +126,11 @@ pub struct ModuleInfo { } /// Mirror version of ModuleInfo that can derive rkyv traits -#[cfg(feature = "enable-rkyv")] #[derive(RkyvSerialize, RkyvDeserialize, Archive)] pub struct ArchivableModuleInfo { name: Option, - imports: ArchivableIndexMap<(String, String, u32), ImportIndex>, - exports: ArchivableIndexMap, + imports: IndexMap<(String, String, u32), ImportIndex>, + exports: IndexMap, start_function: Option, table_initializers: Vec, passive_elements: BTreeMap>, @@ -151,7 +142,7 @@ pub struct ArchivableModuleInfo { tables: PrimaryMap, memories: PrimaryMap, globals: PrimaryMap, - custom_sections: ArchivableIndexMap, + custom_sections: IndexMap, custom_sections_data: PrimaryMap>, num_imported_functions: usize, num_imported_tables: usize, @@ -159,13 +150,12 @@ pub struct ArchivableModuleInfo { num_imported_globals: usize, } -#[cfg(feature = "enable-rkyv")] impl From for ArchivableModuleInfo { fn from(it: ModuleInfo) -> Self { Self { name: it.name, - imports: ArchivableIndexMap::from(it.imports), - exports: ArchivableIndexMap::from(it.exports), + imports: it.imports, + exports: it.exports, start_function: it.start_function, table_initializers: it.table_initializers, passive_elements: it.passive_elements.into_iter().collect(), @@ -177,7 +167,7 @@ impl From for ArchivableModuleInfo { tables: it.tables, memories: it.memories, globals: it.globals, - custom_sections: ArchivableIndexMap::from(it.custom_sections), + custom_sections: it.custom_sections, custom_sections_data: it.custom_sections_data, num_imported_functions: it.num_imported_functions, num_imported_tables: it.num_imported_tables, @@ -187,14 +177,13 @@ impl From for ArchivableModuleInfo { } } -#[cfg(feature = "enable-rkyv")] impl From for ModuleInfo { fn from(it: ArchivableModuleInfo) -> Self { Self { id: Default::default(), name: it.name, - imports: it.imports.into(), - exports: it.exports.into(), + imports: it.imports, + exports: it.exports, start_function: it.start_function, table_initializers: it.table_initializers, passive_elements: it.passive_elements.into_iter().collect(), @@ -206,7 +195,7 @@ impl From for ModuleInfo { tables: it.tables, memories: it.memories, globals: it.globals, - custom_sections: it.custom_sections.into(), + custom_sections: it.custom_sections, custom_sections_data: it.custom_sections_data, num_imported_functions: it.num_imported_functions, num_imported_tables: it.num_imported_tables, @@ -216,14 +205,12 @@ impl From for ModuleInfo { } } -#[cfg(feature = "enable-rkyv")] impl From<&ModuleInfo> for ArchivableModuleInfo { fn from(it: &ModuleInfo) -> Self { Self::from(it.clone()) } } -#[cfg(feature = "enable-rkyv")] impl Archive for ModuleInfo { type Archived = ::Archived; type Resolver = ::Resolver; @@ -233,7 +220,6 @@ impl Archive for ModuleInfo { } } -#[cfg(feature = "enable-rkyv")] impl RkyvSerialize for ModuleInfo { @@ -242,7 +228,6 @@ impl RkyvSerial } } -#[cfg(feature = "enable-rkyv")] impl RkyvDeserialize for Archived { diff --git a/lib/types/src/table.rs b/lib/types/src/table.rs index 5e501a44a9f..2a1d0d743fb 100644 --- a/lib/types/src/table.rs +++ b/lib/types/src/table.rs @@ -1,14 +1,9 @@ -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; /// Implementation styles for WebAssembly tables. -#[derive(Debug, Clone, Hash, PartialEq, Eq)] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(Debug, Clone, Hash, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub enum TableStyle { /// Signatures are stored in the table and checked in the caller. diff --git a/lib/types/src/trapcode.rs b/lib/types/src/trapcode.rs index 64a6d5fab63..21e91929833 100644 --- a/lib/types/src/trapcode.rs +++ b/lib/types/src/trapcode.rs @@ -5,7 +5,6 @@ use core::fmt::{self, Display, Formatter}; use core::str::FromStr; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -14,10 +13,8 @@ use thiserror::Error; /// A trap code describing the reason for a trap. /// /// All trap instructions have an explicit trap code. -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Error)] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) +#[derive( + Clone, Copy, PartialEq, Eq, Debug, Hash, Error, RkyvSerialize, RkyvDeserialize, Archive, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] #[repr(u32)] diff --git a/lib/types/src/types.rs b/lib/types/src/types.rs index 09a805a9e3c..352e84117f5 100644 --- a/lib/types/src/types.rs +++ b/lib/types/src/types.rs @@ -7,7 +7,6 @@ use crate::lib::std::vec::Vec; use crate::units::Pages; use crate::values::{Value, WasmValueType}; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -19,10 +18,7 @@ use serde::{Deserialize, Serialize}; /// A list of all possible value types in WebAssembly. #[derive(Copy, Debug, Clone, Eq, PartialEq, Hash)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive)] pub enum Type { /// Signed 32 bit integer. I32, @@ -64,10 +60,7 @@ impl fmt::Display for Type { #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive)] /// The WebAssembly V128 type pub struct V128(pub(crate) [u8; 16]); @@ -237,10 +230,7 @@ impl ExternType { /// WebAssembly functions can have 0 or more parameters and results. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive)] pub struct FunctionType { /// The parameters of the function params: Box<[Type]>, @@ -326,10 +316,7 @@ impl From<&Self> for FunctionType { /// Indicator of whether a global is mutable or not #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive)] pub enum Mutability { /// The global is constant and its value does not change Const, @@ -366,10 +353,7 @@ impl From for bool { /// WebAssembly global. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive)] pub struct GlobalType { /// The type of the value stored in the global. pub ty: Type, @@ -413,10 +397,7 @@ impl fmt::Display for GlobalType { /// Globals are initialized via the `const` operators or by referring to another import. #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive)] pub enum GlobalInit { /// An `i32.const`. I32Const(i32), @@ -473,10 +454,7 @@ impl GlobalInit { /// which `call_indirect` can invoke other functions. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive)] pub struct TableType { /// The type of data stored in elements of the table. pub ty: Type, @@ -516,10 +494,7 @@ impl fmt::Display for TableType { /// chunks of addressable memory. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) -)] +#[derive(RkyvSerialize, RkyvDeserialize, Archive)] pub struct MemoryType { /// The minimum number of pages in the memory. pub minimum: Pages, diff --git a/lib/types/src/units.rs b/lib/types/src/units.rs index 6ec5d8bd3c6..bb7b08c9843 100644 --- a/lib/types/src/units.rs +++ b/lib/types/src/units.rs @@ -1,7 +1,6 @@ use crate::lib::std::convert::TryFrom; use crate::lib::std::fmt; use crate::lib::std::ops::{Add, Sub}; -#[cfg(feature = "enable-rkyv")] use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; @@ -21,12 +20,10 @@ pub const WASM_MAX_PAGES: u32 = 0x10000; pub const WASM_MIN_PAGES: u32 = 0x100; /// Units of WebAssembly pages (as specified to be 65,536 bytes). -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "enable-rkyv", - derive(RkyvSerialize, RkyvDeserialize, Archive) +#[derive( + Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RkyvSerialize, RkyvDeserialize, Archive, )] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct Pages(pub u32); impl Pages { diff --git a/lib/universal-artifact/Cargo.toml b/lib/universal-artifact/Cargo.toml deleted file mode 100644 index e45c287bc09..00000000000 --- a/lib/universal-artifact/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -description = "Wasmer Engine Universal Artifact abstraction" -categories = ["wasm"] -keywords = ["wasm", "webassembly", "engine"] -authors = ["Wasmer Engineering Team "] -repository = "https://github.com/wasmerio/wasmer" -license = "MIT OR Apache-2.0 WITH LLVM-exception " -readme = "README.md" -edition = "2018" - -[dependencies] -wasmer-artifact = { path = "../artifact", version = "=2.3.0" } -wasmer-types = { path = "../types", version = "=2.3.0" } -wasmer-compiler = { path = "../compiler", version = "=2.3.0", features = ["translator", ] } -thiserror = "1.0" -enumset = "1.0" -rkyv = "0.7.20" -enum-iterator = "0.7.0" - -[features] -compiler = [] - -[badges] -maintenance = { status = "actively-developed" } diff --git a/lib/universal-artifact/README.md b/lib/universal-artifact/README.md deleted file mode 100644 index c02f1c11bc3..00000000000 --- a/lib/universal-artifact/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# `wasmer-engine-universal-artifact` [![Build Status](https://github.com/wasmerio/wasmer/workflows/build/badge.svg?style=flat-square)](https://github.com/wasmerio/wasmer/actions?query=workflow%3Abuild) [![Join Wasmer Slack](https://img.shields.io/static/v1?label=Slack&message=join%20chat&color=brighgreen&style=flat-square)](https://slack.wasmer.io) [![MIT License](https://img.shields.io/github/license/wasmerio/wasmer.svg?style=flat-square)](https://github.com/wasmerio/wasmer/blob/master/LICENSE) - - -This crate is the general abstraction for generating Artifacts in Wasmer. - -### Acknowledgments - -This project borrowed some of the code of the trap implementation from -the [`wasmtime-api`], the code since then has evolved significantly. - -Please check [Wasmer `ATTRIBUTIONS`] to further see licenses and other -attributions of the project. - - -[`wasmer-engine-universal`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-universal -[`wasmer-engine-dylib`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-dylib -[`wasmer-engine-staticlib`]: https://github.com/wasmerio/wasmer/tree/master/lib/engine-staticlib -[`wasmer-engine-dummy`]: https://github.com/wasmerio/wasmer/tree/master/tests/lib/engine-dummy -[`wasmtime-api`]: https://crates.io/crates/wasmtime -[Wasmer `ATTRIBUTIONS`]: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md diff --git a/lib/universal-artifact/src/lib.rs b/lib/universal-artifact/src/lib.rs deleted file mode 100644 index d3843a5882e..00000000000 --- a/lib/universal-artifact/src/lib.rs +++ /dev/null @@ -1,34 +0,0 @@ -//! Generic Artifact abstraction for Wasmer Engines. - -#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)] -#![warn(unused_import_braces)] -#![cfg_attr( - feature = "cargo-clippy", - allow(clippy::new_without_default, clippy::new_without_default) -)] -#![cfg_attr( - feature = "cargo-clippy", - warn( - clippy::float_arithmetic, - clippy::mut_mut, - clippy::nonminimal_bool, - clippy::map_unwrap_or, - clippy::print_stdout, - clippy::unicode_not_nfc, - clippy::use_self - ) -)] - -mod artifact; -mod engine; -mod serialize; -mod trampoline; - -pub use crate::artifact::UniversalArtifactBuild; -pub use crate::engine::UniversalEngineBuilder; -pub use crate::serialize::SerializableModule; -pub use crate::trampoline::*; -pub use wasmer_artifact::{ArtifactCreate, MetadataHeader, Upcastable}; - -/// Version number of this crate. -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/lib/vm/Cargo.toml b/lib/vm/Cargo.toml index d76e0a95fd7..907a6602c64 100644 --- a/lib/vm/Cargo.toml +++ b/lib/vm/Cargo.toml @@ -12,7 +12,6 @@ edition = "2018" [dependencies] wasmer-types = { path = "../types", version = "=2.3.0" } -wasmer-artifact = { path = "../artifact", version = "=2.3.0" } libc = { version = "^0.2", default-features = false } memoffset = "0.6" indexmap = { version = "1.6", features = ["serde-1"] } @@ -21,7 +20,7 @@ more-asserts = "0.2" cfg-if = "1.0" backtrace = "0.3" serde = { version = "1.0", features = ["derive", "rc"] } -rkyv = { version = "0.7.20", optional = true } +rkyv = { version = "0.7.38", features = ["indexmap"] } enum-iterator = "0.7.0" scopeguard = "1.1.0" lazy_static = "1.4.0" @@ -42,4 +41,3 @@ maintenance = { status = "actively-developed" } [features] default = [] -enable-rkyv = ["rkyv"] diff --git a/lib/vm/src/export.rs b/lib/vm/src/export.rs index be6e5e57533..d50792c5359 100644 --- a/lib/vm/src/export.rs +++ b/lib/vm/src/export.rs @@ -5,7 +5,8 @@ use crate::global::Global; use crate::instance::WeakOrStrongInstanceRef; use crate::memory::Memory; use crate::table::Table; -use crate::vmcontext::{VMFunctionBody, VMFunctionEnvironment, VMFunctionKind, VMTrampoline}; +use crate::vmcontext::{VMFunctionEnvironment, VMFunctionKind, VMTrampoline}; +use crate::VMFunctionBody; use std::sync::Arc; use wasmer_types::{FunctionType, MemoryStyle, MemoryType, TableStyle, TableType}; diff --git a/lib/vm/src/instance/mod.rs b/lib/vm/src/instance/mod.rs index f7671196694..d9110fb4aa1 100644 --- a/lib/vm/src/instance/mod.rs +++ b/lib/vm/src/instance/mod.rs @@ -21,12 +21,11 @@ use crate::memory::{Memory, MemoryError}; use crate::table::{Table, TableElement}; use crate::trap::{catch_traps, Trap, TrapCode, TrapHandler}; use crate::vmcontext::{ - VMBuiltinFunctionsArray, VMCallerCheckedAnyfunc, VMContext, VMFunctionBody, - VMFunctionEnvironment, VMFunctionImport, VMFunctionKind, VMGlobalDefinition, VMGlobalImport, - VMMemoryDefinition, VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition, VMTableImport, - VMTrampoline, + VMBuiltinFunctionsArray, VMCallerCheckedAnyfunc, VMContext, VMFunctionEnvironment, + VMFunctionImport, VMFunctionKind, VMGlobalDefinition, VMGlobalImport, VMMemoryDefinition, + VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition, VMTableImport, VMTrampoline, }; -use crate::{FunctionBodyPtr, VMOffsets}; +use crate::{FunctionBodyPtr, VMFunctionBody, VMOffsets}; use crate::{VMFunction, VMGlobal, VMMemory, VMTable}; use memoffset::offset_of; use more_asserts::assert_lt; diff --git a/lib/vm/src/lib.rs b/lib/vm/src/lib.rs index 03bc0330d03..1e5edd2d79f 100644 --- a/lib/vm/src/lib.rs +++ b/lib/vm/src/lib.rs @@ -54,7 +54,6 @@ pub use crate::vmcontext::{ VMFunctionImport, VMFunctionKind, VMGlobalDefinition, VMGlobalImport, VMMemoryDefinition, VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition, VMTableImport, VMTrampoline, }; -pub use wasmer_artifact::{FunctionBodyPtr, VMFunctionBody}; pub use wasmer_types::LibCall; pub use wasmer_types::MemoryStyle; pub use wasmer_types::TableStyle; @@ -82,3 +81,43 @@ impl std::ops::Deref for SectionBodyPtr { &self.0 } } + +/// A placeholder byte-sized type which is just used to provide some amount of type +/// safety when dealing with pointers to JIT-compiled function bodies. Note that it's +/// deliberately not Copy, as we shouldn't be carelessly copying function body bytes +/// around. +#[repr(C)] +pub struct VMFunctionBody(u8); + +#[cfg(test)] +mod test_vmfunction_body { + use super::VMFunctionBody; + use std::mem::size_of; + + #[test] + fn check_vmfunction_body_offsets() { + assert_eq!(size_of::(), 1); + } +} + +/// A safe wrapper around `VMFunctionBody`. +#[derive(Clone, Copy, Debug)] +#[repr(transparent)] +pub struct FunctionBodyPtr(pub *const VMFunctionBody); + +impl std::ops::Deref for FunctionBodyPtr { + type Target = *const VMFunctionBody; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +/// # Safety +/// The VMFunctionBody that this points to is opaque, so there's no data to +/// read or write through this pointer. This is essentially a usize. +unsafe impl Send for FunctionBodyPtr {} +/// # Safety +/// The VMFunctionBody that this points to is opaque, so there's no data to +/// read or write through this pointer. This is essentially a usize. +unsafe impl Sync for FunctionBodyPtr {} diff --git a/lib/vm/src/trap/traphandlers.rs b/lib/vm/src/trap/traphandlers.rs index 21b26782950..263e532845e 100644 --- a/lib/vm/src/trap/traphandlers.rs +++ b/lib/vm/src/trap/traphandlers.rs @@ -4,8 +4,8 @@ //! WebAssembly trap handling, which is built on top of the lower-level //! signalhandling mechanisms. -use crate::vmcontext::{VMFunctionBody, VMFunctionEnvironment, VMTrampoline}; -use crate::Trap; +use crate::vmcontext::{VMFunctionEnvironment, VMTrampoline}; +use crate::{Trap, VMFunctionBody}; use backtrace::Backtrace; use core::ptr::{read, read_unaligned}; use corosensei::stack::DefaultStack; diff --git a/lib/vm/src/vmcontext.rs b/lib/vm/src/vmcontext.rs index cb5f0ccb51c..bb2257d149f 100644 --- a/lib/vm/src/vmcontext.rs +++ b/lib/vm/src/vmcontext.rs @@ -12,13 +12,13 @@ use crate::table::Table; use crate::trap::{Trap, TrapCode}; use crate::VMBuiltinFunctionIndex; use crate::VMExternRef; +use crate::VMFunctionBody; use std::any::Any; use std::convert::TryFrom; use std::fmt; use std::ptr::{self, NonNull}; use std::sync::Arc; use std::u32; -pub use wasmer_artifact::VMFunctionBody; /// Union representing the first parameter passed when calling a function. /// diff --git a/scripts/publish.py b/scripts/publish.py index 1e9dfb34198..6cc7884bc94 100644 --- a/scripts/publish.py +++ b/scripts/publish.py @@ -59,26 +59,6 @@ "wasmer-engine", ] ), - "wasmer-engine-dylib": set( - [ - "wasmer-artifact", - "wasmer-types", - "wasmer-compiler", - "wasmer-vm", - "wasmer-engine", - "wasmer-object", - ] - ), - "wasmer-engine-staticlib": set( - [ - "wasmer-artifact", - "wasmer-types", - "wasmer-compiler", - "wasmer-vm", - "wasmer-engine", - "wasmer-object", - ] - ), "wasmer": set( [ "wasmer-artifact", @@ -91,7 +71,6 @@ "wasmer-compiler-cranelift", "wasmer-compiler-llvm", "wasmer-engine-universal", - "wasmer-engine-dylib", ] ), "wasmer-vfs": set([]), @@ -110,8 +89,6 @@ "wasmer-emscripten", "wasmer-engine", "wasmer-engine-universal", - "wasmer-engine-dylib", - "wasmer-engine-staticlib", "wasmer-middlewares", "wasmer-wasi", "wasmer-types", @@ -129,8 +106,6 @@ "wasmer-emscripten", "wasmer-engine", "wasmer-engine-universal", - "wasmer-engine-dylib", - "wasmer-engine-staticlib", "wasmer-vm", "wasmer-wasi", "wasmer-wasi-experimental-io-devices", @@ -159,8 +134,6 @@ "wasmer-compiler-llvm": "compiler-llvm", "wasmer-engine": "engine", "wasmer-engine-universal": "engine-universal", - "wasmer-engine-dylib": "engine-dylib", - "wasmer-engine-staticlib": "engine-staticlib", "wasmer-cache": "cache", "wasmer": "api", "wasmer-wasi": "wasi", diff --git a/tests/compilers/config.rs b/tests/compilers/config.rs index 28c35b7cbf8..c48bff040b5 100644 --- a/tests/compilers/config.rs +++ b/tests/compilers/config.rs @@ -1,5 +1,5 @@ use std::sync::Arc; -use wasmer::{CompilerConfig, Engine as WasmerEngine, Features, ModuleMiddleware, Store}; +use wasmer::{CompilerConfig, Engine, Features, ModuleMiddleware, Store}; #[derive(Clone, Debug, PartialEq)] pub enum Compiler { @@ -8,26 +8,18 @@ pub enum Compiler { Singlepass, } -#[derive(Clone, Debug, PartialEq)] -pub enum Engine { - Dylib, - Universal, -} - #[derive(Clone)] pub struct Config { pub compiler: Compiler, - pub engine: Engine, pub features: Option, pub middlewares: Vec>, pub canonicalize_nans: bool, } impl Config { - pub fn new(engine: Engine, compiler: Compiler) -> Self { + pub fn new(compiler: Compiler) -> Self { Self { compiler, - engine, features: None, canonicalize_nans: false, middlewares: vec![], @@ -49,54 +41,24 @@ impl Config { pub fn store(&self) -> Store { let compiler_config = self.compiler_config(self.canonicalize_nans); let engine = self.engine(compiler_config); - Store::new(&*engine) + Store::new_with_engine(&*engine) } pub fn headless_store(&self) -> Store { let engine = self.engine_headless(); - Store::new(&*engine) + Store::new_with_engine(&*engine) } - pub fn engine(&self, compiler_config: Box) -> Box { - #[cfg(not(feature = "engine"))] - compile_error!("Plese enable at least one engine via the features"); - match &self.engine { - #[cfg(feature = "dylib")] - Engine::Dylib => { - let mut engine = wasmer_engine_dylib::Dylib::new(compiler_config); - if let Some(ref features) = self.features { - engine = engine.features(features.clone()) - } - Box::new(engine.engine()) - } - #[cfg(feature = "universal")] - Engine::Universal => { - let mut engine = wasmer_engine_universal::Universal::new(compiler_config); - if let Some(ref features) = self.features { - engine = engine.features(features.clone()) - } - Box::new(engine.engine()) - } - #[allow(unreachable_patterns)] - engine => panic!( - "The {:?} Engine is not enabled. Please enable it using the features", - engine - ), + pub fn engine(&self, compiler_config: Box) -> Box { + let mut engine = wasmer_compiler::Universal::new(compiler_config); + if let Some(ref features) = self.features { + engine = engine.features(features.clone()) } + Box::new(engine.engine()) } - pub fn engine_headless(&self) -> Box { - match &self.engine { - #[cfg(feature = "dylib")] - Engine::Dylib => Box::new(wasmer_engine_dylib::Dylib::headless().engine()), - #[cfg(feature = "universal")] - Engine::Universal => Box::new(wasmer_engine_universal::Universal::headless().engine()), - #[allow(unreachable_patterns)] - engine => panic!( - "The {:?} Engine is not enabled. Please enable it using the features", - engine - ), - } + pub fn engine_headless(&self) -> Box { + Box::new(wasmer_compiler::Universal::headless().engine()) } pub fn compiler_config( diff --git a/tests/compilers/main.rs b/tests/compilers/main.rs index 9ba00794f68..67606398ea9 100644 --- a/tests/compilers/main.rs +++ b/tests/compilers/main.rs @@ -18,7 +18,7 @@ mod traps; mod wasi; mod wast; -pub use crate::config::{Compiler, Config, Engine}; +pub use crate::config::{Compiler, Config}; pub use crate::wasi::run_wasi; pub use crate::wast::run_wast; pub use wasmer_wast::WasiFileSystemKind; diff --git a/tests/compilers/wast.rs b/tests/compilers/wast.rs index 17ffb6f0bcf..576e62e19fa 100644 --- a/tests/compilers/wast.rs +++ b/tests/compilers/wast.rs @@ -42,16 +42,6 @@ pub fn run_wast(mut config: crate::Config, wast_path: &str) -> anyhow::Result<() wast.allow_trap_message("uninitialized element 2", "uninitialized element"); // `liking.wast` has different wording but the same meaning wast.allow_trap_message("out of bounds memory access", "memory out of bounds"); - if config.compiler == crate::Compiler::Cranelift && config.engine == crate::Engine::Dylib { - wast.allow_trap_message("call stack exhausted", "out of bounds memory access"); - wast.allow_trap_message("indirect call type mismatch", "call stack exhausted"); - wast.allow_trap_message("integer divide by zero", "call stack exhausted"); - wast.allow_trap_message("integer overflow", "call stack exhausted"); - wast.allow_trap_message("invalid conversion to integer", "call stack exhausted"); - wast.allow_trap_message("undefined element", "call stack exhausted"); - wast.allow_trap_message("uninitialized element", "call stack exhausted"); - wast.allow_trap_message("unreachable", "call stack exhausted"); - } if cfg!(feature = "coverage") { wast.disable_assert_and_exhaustion(); } diff --git a/tests/ignores.txt b/tests/ignores.txt index 4654af9d99a..0ca0216d98f 100644 --- a/tests/ignores.txt +++ b/tests/ignores.txt @@ -2,37 +2,27 @@ singlepass spec::multi_value # Singlepass has not implemented multivalue (functions that returns "structs"/"tuples") singlepass spec::simd # Singlepass doesn't support yet SIMD (no one asked for this feature) -windows+dylib * # This might be trivial to fix? -musl+dylib * # Dynamic loading not supported in Musl - # Traps ## Traps. Tracing doesn't work properly in Singlepass ## Unwinding is not properly implemented in Singlepass # Needs investigation singlepass+aarch64+macos traps::test_trap_trace -dylib traps::test_trap_trace cranelift+aarch64 traps::test_trap_trace singlepass+aarch64+macos traps::test_trap_stack_overflow # Need to investigate -dylib traps::test_trap_stack_overflow # Need to investigate cranelift+aarch64 traps::test_trap_stack_overflow # Need to investigate singlepass+aarch64+macos traps::trap_display_pretty llvm traps::trap_display_pretty -dylib traps::trap_display_pretty cranelift+aarch64 traps::trap_display_pretty singlepass+aarch64+macos traps::trap_display_multi_module llvm traps::trap_display_multi_module -dylib traps::trap_display_multi_module cranelift+aarch64 traps::trap_display_multi_module singlepass traps::call_signature_mismatch # Need to investigate, get foo (a[0]:0x33) instead of 0x30 for inderect call llvm traps::call_signature_mismatch -dylib traps::call_signature_mismatch macos+aarch64 traps::call_signature_mismatch singlepass+aarch64+macos traps::start_trap_pretty llvm traps::start_trap_pretty -dylib traps::start_trap_pretty cranelift+aarch64 traps::start_trap_pretty -singlepass multi_value_imports::dylib # Singlepass doesn't support multivalue singlepass multi_value_imports::dynamic # Singlepass doesn't support multivalue # Also neither LLVM nor Cranelift currently implement stack probing on AArch64. diff --git a/tests/integration/cli/build.rs b/tests/integration/cli/build.rs new file mode 100644 index 00000000000..81caa36d691 --- /dev/null +++ b/tests/integration/cli/build.rs @@ -0,0 +1,6 @@ +fn main() { + println!( + "cargo:rustc-env=TARGET={}", + std::env::var("TARGET").unwrap() + ); +} diff --git a/tests/integration/cli/src/assets.rs b/tests/integration/cli/src/assets.rs index e4ebf38d053..c3700707d1f 100644 --- a/tests/integration/cli/src/assets.rs +++ b/tests/integration/cli/src/assets.rs @@ -18,25 +18,76 @@ pub const WASMER_PATH: &str = concat!( "/../../../target/release/wasmer" ); +#[cfg(feature = "debug")] +pub const WASMER_TARGET_PATH: &str = concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../../", + env!("CARGO_CFG_TARGET"), + "/debug/wasmer" +); + +/* env var TARGET is set by tests/integration/cli/build.rs on compile-time */ + +#[cfg(not(feature = "debug"))] +pub const WASMER_TARGET_PATH: &str = concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../../target/", + env!("TARGET"), + "/release/wasmer" +); + #[cfg(not(windows))] pub const LIBWASMER_PATH: &str = concat!( env!("CARGO_MANIFEST_DIR"), "/../../../target/release/libwasmer.a" ); + #[cfg(windows)] pub const LIBWASMER_PATH: &str = concat!( env!("CARGO_MANIFEST_DIR"), "/../../../target/release/wasmer.lib" ); +#[cfg(not(windows))] +pub const LIBWASMER_TARGET_PATH: &str = concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../../target", + env!("TARGET"), + "/release/libwasmer.a" +); + +#[cfg(windows)] +pub const LIBWASMER_TARGET_PATH: &str = concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../../", + env!("TARGET"), + "/release/wasmer.lib" +); + /// Get the path to the `libwasmer.a` static library. pub fn get_libwasmer_path() -> PathBuf { - PathBuf::from( + let mut ret = PathBuf::from( env::var("WASMER_TEST_LIBWASMER_PATH").unwrap_or_else(|_| LIBWASMER_PATH.to_string()), - ) + ); + if !ret.exists() { + ret = PathBuf::from(LIBWASMER_TARGET_PATH.to_string()); + } + if !ret.exists() { + panic!("Could not find libwasmer path! {:?}", ret); + } + ret } /// Get the path to the `wasmer` executable to be used in this test. pub fn get_wasmer_path() -> PathBuf { - PathBuf::from(env::var("WASMER_TEST_WASMER_PATH").unwrap_or_else(|_| WASMER_PATH.to_string())) + let mut ret = PathBuf::from( + env::var("WASMER_TEST_WASMER_PATH").unwrap_or_else(|_| WASMER_PATH.to_string()), + ); + if !ret.exists() { + ret = PathBuf::from(WASMER_TARGET_PATH.to_string()); + } + if !ret.exists() { + panic!("Could not find wasmer executable path! {:?}", ret); + } + ret } diff --git a/tests/integration/cli/src/util.rs b/tests/integration/cli/src/util.rs index 5ec991e3c71..fcd5f248461 100644 --- a/tests/integration/cli/src/util.rs +++ b/tests/integration/cli/src/util.rs @@ -19,23 +19,6 @@ impl Compiler { } } -#[derive(Debug, Copy, Clone)] -pub enum Engine { - Universal, - Dylib, - Staticlib, -} - -impl Engine { - pub const fn to_flag(self) -> &'static str { - match self { - Engine::Universal => "--universal", - Engine::Dylib => "--dylib", - Engine::Staticlib => "--staticlib", - } - } -} - pub fn run_code( operating_dir: &Path, executable_path: &Path, diff --git a/tests/integration/cli/tests/compile.rs b/tests/integration/cli/tests/compile.rs deleted file mode 100644 index 8cba88de268..00000000000 --- a/tests/integration/cli/tests/compile.rs +++ /dev/null @@ -1,172 +0,0 @@ -//! CLI tests for the compile subcommand. - -use anyhow::{bail, Context}; -use std::fs; -use std::io::Write; -use std::path::{Path, PathBuf}; -use std::process::Command; -use wasmer_integration_tests_cli::link_code::*; -use wasmer_integration_tests_cli::*; - -const STATICLIB_ENGINE_TEST_C_SOURCE: &[u8] = include_bytes!("staticlib_engine_test_c_source.c"); - -fn staticlib_engine_test_wasm_path() -> String { - format!("{}/{}", C_ASSET_PATH, "qjs.wasm") -} - -/// Data used to run the `wasmer compile` command. -#[derive(Debug)] -struct WasmerCompile { - /// The directory to operate in. - current_dir: PathBuf, - /// Path to wasmer executable used to run the command. - wasmer_path: PathBuf, - /// Path to the Wasm file to compile. - wasm_path: PathBuf, - /// Path to the static object file produced by compiling the Wasm. - wasm_object_path: PathBuf, - /// Path to output the generated header to. - header_output_path: PathBuf, - /// Compiler with which to compile the Wasm. - compiler: Compiler, - /// Engine with which to use to generate the artifacts. - engine: Engine, -} - -impl Default for WasmerCompile { - fn default() -> Self { - #[cfg(not(windows))] - let wasm_obj_path = "wasm.o"; - #[cfg(windows)] - let wasm_obj_path = "wasm.obj"; - Self { - current_dir: std::env::current_dir().unwrap(), - wasmer_path: get_wasmer_path(), - wasm_path: PathBuf::from(staticlib_engine_test_wasm_path()), - wasm_object_path: PathBuf::from(wasm_obj_path), - header_output_path: PathBuf::from("my_wasm.h"), - compiler: Compiler::Cranelift, - engine: Engine::Staticlib, - } - } -} - -impl WasmerCompile { - fn run(&self) -> anyhow::Result<()> { - let output = Command::new(&self.wasmer_path) - .current_dir(&self.current_dir) - .arg("compile") - .arg(&self.wasm_path.canonicalize()?) - .arg(&self.compiler.to_flag()) - .arg(&self.engine.to_flag()) - .arg("-o") - .arg(&self.wasm_object_path) - .arg("--header") - .arg(&self.header_output_path) - .output()?; - - if !output.status.success() { - bail!( - "wasmer compile failed with: stdout: {}\n\nstderr: {}", - std::str::from_utf8(&output.stdout) - .expect("stdout is not utf8! need to handle arbitrary bytes"), - std::str::from_utf8(&output.stderr) - .expect("stderr is not utf8! need to handle arbitrary bytes") - ); - } - Ok(()) - } -} - -/// Compile the C code. -fn run_c_compile( - current_dir: &Path, - path_to_c_src: &Path, - output_name: &Path, -) -> anyhow::Result<()> { - #[cfg(not(windows))] - let c_compiler = "cc"; - #[cfg(windows)] - let c_compiler = "clang++"; - - let output = Command::new(c_compiler) - .current_dir(current_dir) - .arg("-O2") - .arg("-c") - .arg(path_to_c_src) - .arg("-I") - .arg(WASMER_INCLUDE_PATH) - .arg("-o") - .arg(output_name) - .output()?; - - if !output.status.success() { - bail!( - "C code compile failed with: stdout: {}\n\nstderr: {}", - std::str::from_utf8(&output.stdout) - .expect("stdout is not utf8! need to handle arbitrary bytes"), - std::str::from_utf8(&output.stderr) - .expect("stderr is not utf8! need to handle arbitrary bytes") - ); - } - Ok(()) -} - -#[test] -fn staticlib_engine_works() -> anyhow::Result<()> { - let temp_dir = tempfile::tempdir().context("Making a temp dir")?; - let operating_dir: PathBuf = temp_dir.path().to_owned(); - - let wasm_path = operating_dir.join(staticlib_engine_test_wasm_path()); - #[cfg(not(windows))] - let wasm_object_path = operating_dir.join("wasm.o"); - #[cfg(windows)] - let wasm_object_path = operating_dir.join("wasm.obj"); - let header_output_path = operating_dir.join("my_wasm.h"); - - WasmerCompile { - current_dir: operating_dir.clone(), - wasm_path, - wasm_object_path: wasm_object_path.clone(), - header_output_path, - compiler: Compiler::Cranelift, - engine: Engine::Staticlib, - ..Default::default() - } - .run() - .context("Failed to compile wasm with Wasmer")?; - - let c_src_file_name = operating_dir.join("c_src.c"); - #[cfg(not(windows))] - let c_object_path = operating_dir.join("c_src.o"); - #[cfg(windows)] - let c_object_path = operating_dir.join("c_src.obj"); - let executable_path = operating_dir.join("a.out"); - - // TODO: adjust C source code based on locations of things - { - let mut c_src_file = fs::OpenOptions::new() - .create_new(true) - .write(true) - .open(&c_src_file_name) - .context("Failed to open C source code file")?; - c_src_file.write_all(STATICLIB_ENGINE_TEST_C_SOURCE)?; - } - run_c_compile(&operating_dir, &c_src_file_name, &c_object_path) - .context("Failed to compile C source code")?; - LinkCode { - current_dir: operating_dir.clone(), - object_paths: vec![c_object_path, wasm_object_path], - output_path: executable_path.clone(), - ..Default::default() - } - .run() - .context("Failed to link objects together")?; - - let result = run_code(&operating_dir, &executable_path, &[]) - .context("Failed to run generated executable")?; - let result_lines = result.lines().collect::>(); - assert_eq!(result_lines, vec!["Initializing...", "\"Hello, World\""],); - - Ok(()) -} diff --git a/tests/integration/cli/tests/staticlib_engine_test_c_source.c b/tests/integration/cli/tests/staticlib_engine_test_c_source.c deleted file mode 100644 index 0a3bc08878c..00000000000 --- a/tests/integration/cli/tests/staticlib_engine_test_c_source.c +++ /dev/null @@ -1,102 +0,0 @@ -#include "wasmer.h" -#include "my_wasm.h" - -#include -#include - -#define own - -static void print_wasmer_error() { - int error_len = wasmer_last_error_length(); - if (error_len > 0) { - printf("Error len: `%d`\n", error_len); - char *error_str = (char *)malloc(error_len); - wasmer_last_error_message(error_str, error_len); - printf("Error str: `%s`\n", error_str); - free(error_str); - } -} - -int main() { - printf("Initializing...\n"); - wasm_config_t *config = wasm_config_new(); - wasm_config_set_engine(config, STATICLIB); - wasm_engine_t *engine = wasm_engine_new_with_config(config); - wasm_store_t *store = wasm_store_new(engine); - - wasm_module_t *module = wasmer_staticlib_engine_new(store, "qjs.wasm"); - - if (!module) { - printf("Failed to create module\n"); - print_wasmer_error(); - return -1; - } - - // We have now finished the memory buffer book keeping and we have a valid - // Module. - - // In this example we're passing some JavaScript source code as a command line - // argument to a WASI module that can evaluate JavaScript. - wasi_config_t *wasi_config = wasi_config_new("constant_value_here"); - const char *js_string = - "function greet(name) { return JSON.stringify('Hello, ' + name); }; " - "print(greet('World'));"; - wasi_config_arg(wasi_config, "--eval"); - wasi_config_arg(wasi_config, js_string); - wasi_env_t *wasi_env = wasi_env_new(wasi_config); - - if (!wasi_env) { - printf("> Error building WASI env!\n"); - print_wasmer_error(); - return 1; - } - - wasm_importtype_vec_t import_types; - wasm_module_imports(module, &import_types); - - wasm_extern_vec_t imports; - wasm_extern_vec_new_uninitialized(&imports, import_types.size); - wasm_importtype_vec_delete(&import_types); - - bool get_imports_result = wasi_get_imports(store, module, wasi_env, &imports); - wasi_env_delete(wasi_env); - - if (!get_imports_result) { - printf("> Error getting WASI imports!\n"); - print_wasmer_error(); - return 1; - } - - wasm_instance_t *instance = wasm_instance_new(store, module, &imports, NULL); - - if (!instance) { - printf("Failed to create instance\n"); - print_wasmer_error(); - return -1; - } - - // WASI is now set up. - own wasm_func_t *start_function = wasi_get_start_function(instance); - if (!start_function) { - fprintf(stderr, "`_start` function not found\n"); - print_wasmer_error(); - return -1; - } - - fflush(stdout); - - wasm_val_vec_t args = WASM_EMPTY_VEC; - wasm_val_vec_t results = WASM_EMPTY_VEC; - own wasm_trap_t *trap = wasm_func_call(start_function, &args, &results); - if (trap) { - fprintf(stderr, "Trap is not NULL: TODO:\n"); - return -1; - } - - wasm_instance_delete(instance); - wasm_module_delete(module); - wasm_store_delete(store); - wasm_engine_delete(engine); - - return 0; -} diff --git a/tests/lib/compiler-test-derive/src/ignores.rs b/tests/lib/compiler-test-derive/src/ignores.rs index 4075d86a4a3..59a13549dfc 100644 --- a/tests/lib/compiler-test-derive/src/ignores.rs +++ b/tests/lib/compiler-test-derive/src/ignores.rs @@ -115,7 +115,7 @@ impl Ignores { arch = Some(alias.to_string()); } // Engines - "universal" | "dylib" => { + "universal" => { engine = Some(alias.to_string()); } // Compilers diff --git a/tests/lib/compiler-test-derive/src/lib.rs b/tests/lib/compiler-test-derive/src/lib.rs index c9e5001d68a..79c5ecdff9e 100644 --- a/tests/lib/compiler-test-derive/src/lib.rs +++ b/tests/lib/compiler-test-derive/src/lib.rs @@ -74,7 +74,6 @@ pub fn compiler_test(attrs: TokenStream, input: TokenStream) -> TokenStream { engine_feature_name: &str| -> ::proc_macro2::TokenStream { let config_compiler = ::quote::format_ident!("{}", compiler_name); - let config_engine = ::quote::format_ident!("{}", engine_name); let test_name = ::quote::format_ident!("{}", engine_name.to_lowercase()); let mut new_sig = func.sig.clone(); let attrs = func @@ -89,7 +88,7 @@ pub fn compiler_test(attrs: TokenStream, input: TokenStream) -> TokenStream { #attrs #[cfg(feature = #engine_feature_name)] #new_sig { - #fn_name(crate::Config::new(crate::Engine::#config_engine, crate::Compiler::#config_compiler)) + #fn_name(crate::Config::new(crate::Compiler::#config_compiler)) } }; if should_ignore( @@ -112,7 +111,6 @@ pub fn compiler_test(attrs: TokenStream, input: TokenStream) -> TokenStream { let mod_name = ::quote::format_ident!("{}", compiler_name.to_lowercase()); let universal_engine_test = construct_engine_test(func, compiler_name, "Universal", "universal"); - let dylib_engine_test = construct_engine_test(func, compiler_name, "Dylib", "dylib"); let compiler_name_lowercase = compiler_name.to_lowercase(); quote! { @@ -121,7 +119,6 @@ pub fn compiler_test(attrs: TokenStream, input: TokenStream) -> TokenStream { use super::*; #universal_engine_test - #dylib_engine_test } } }; diff --git a/tests/lib/compiler-test-derive/src/tests.rs b/tests/lib/compiler-test-derive/src/tests.rs index 1833479762d..00dbdc801fd 100644 --- a/tests/lib/compiler-test-derive/src/tests.rs +++ b/tests/lib/compiler-test-derive/src/tests.rs @@ -59,16 +59,6 @@ gen_tests! { #[cfg(feature = "universal")] fn universal() { foo(crate::Config::new( - crate::Engine::Universal, - crate::Compiler::Singlepass - )) - } - #[test_log::test] - #[cold] - #[cfg(feature = "dylib")] - fn dylib() { - foo(crate::Config::new( - crate::Engine::Dylib, crate::Compiler::Singlepass )) } @@ -82,16 +72,6 @@ gen_tests! { #[cfg(feature = "universal")] fn universal() { foo(crate::Config::new( - crate::Engine::Universal, - crate::Compiler::Cranelift - )) - } - #[test_log::test] - #[cold] - #[cfg(feature = "dylib")] - fn dylib() { - foo(crate::Config::new( - crate::Engine::Dylib, crate::Compiler::Cranelift )) } @@ -105,16 +85,6 @@ gen_tests! { #[cfg(feature = "universal")] fn universal() { foo(crate::Config::new( - crate::Engine::Universal, - crate::Compiler::LLVM - )) - } - #[test_log::test] - #[cold] - #[cfg(feature = "dylib")] - fn dylib() { - foo(crate::Config::new( - crate::Engine::Dylib, crate::Compiler::LLVM )) } diff --git a/tests/lib/engine-dummy/Cargo.toml b/tests/lib/engine-dummy/Cargo.toml deleted file mode 100644 index 95b67d86d0a..00000000000 --- a/tests/lib/engine-dummy/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "wasmer-engine-dummy" -version = "2.3.0" -authors = ["Wasmer Engineering Team "] -description = "Wasmer placeholder engine" -license = "MIT" -edition = "2018" -publish = false - -[dependencies] -wasmer-artifact = { path = "../../../lib/artifact", version = "=2.3.0" } -wasmer-types = { path = "../../../lib/types", version = "=2.3.0" } -wasmer-compiler = { path = "../../../lib/compiler", version = "=2.3.0" } -wasmer-vm = { path = "../../../lib/vm", version = "=2.3.0" } -wasmer-engine = { path = "../../../lib/engine", version = "=2.3.0" } -serde = { version = "1.0", features = ["derive", "rc"], optional = true } -serde_bytes = { version = "0.11", optional = true } -bincode = { version = "1.2", optional = true } -enumset = "1.0" - -[features] -# Enable the `compiler` feature if you want the engine to compile -# and not be only on headless mode. -default = ["serialize", "compiler"] -compiler = ["wasmer-compiler/translator"] -serialize = ["serde", "serde_bytes", "bincode"] - -[badges] -# TODO: publish this crate again and deprecate it -maintenance = { status = "actively-developed" } diff --git a/tests/lib/engine-dummy/README.md b/tests/lib/engine-dummy/README.md deleted file mode 100644 index 50811ddedde..00000000000 --- a/tests/lib/engine-dummy/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Wasmer Dummy Engine - -The Dummy engine is mainly using for testing and learning proposes. -We use it for testing compiler-less code on the `wasmer` API -to make sure the API behaves as we expect. - -It can also be used to learn on how to implement a custom engine for Wasmer. - -A dummy engine, can't instantiate a Module. However it can inspect the -information related to `ModuleInfo`. \ No newline at end of file diff --git a/tests/lib/engine-dummy/src/artifact.rs b/tests/lib/engine-dummy/src/artifact.rs deleted file mode 100644 index 4d6cbd5b400..00000000000 --- a/tests/lib/engine-dummy/src/artifact.rs +++ /dev/null @@ -1,267 +0,0 @@ -//! Define `DummyArtifact` to allow compiling and instantiating to be -//! done as separate steps. - -use crate::engine::DummyEngine; -use enumset::EnumSet; -#[cfg(feature = "serialize")] -use serde::{Deserialize, Serialize}; -use std::sync::Arc; -use wasmer_artifact::ArtifactCreate; -#[cfg(feature = "compiler")] -use wasmer_compiler::ModuleEnvironment; -use wasmer_compiler::{CompileError, CpuFeature}; -use wasmer_engine::{Artifact, DeserializeError, Engine as _, SerializeError, Tunables}; -use wasmer_types::entity::{BoxedSlice, PrimaryMap}; -use wasmer_types::{ - Features, FunctionIndex, LocalFunctionIndex, MemoryIndex, ModuleInfo, OwnedDataInitializer, - SignatureIndex, TableIndex, -}; -use wasmer_vm::{ - FuncDataRegistry, FunctionBodyPtr, MemoryStyle, TableStyle, VMContext, VMFunctionBody, - VMSharedSignatureIndex, VMTrampoline, -}; - -/// Serializable struct for the artifact -#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] -pub struct DummyArtifactMetadata { - pub module: Arc, - pub features: Features, - pub data_initializers: Box<[OwnedDataInitializer]>, - // Plans for that module - pub memory_styles: PrimaryMap, - pub table_styles: PrimaryMap, - pub cpu_features: u64, -} - -/// A Dummy artifact. -/// -/// This artifact will point to fake finished functions and trampolines -/// as no functions are really compiled. -pub struct DummyArtifact { - metadata: DummyArtifactMetadata, - finished_functions: BoxedSlice, - finished_function_call_trampolines: BoxedSlice, - finished_dynamic_function_trampolines: BoxedSlice, - signatures: BoxedSlice, - func_data_registry: Arc, -} - -extern "C" fn dummy_function(_context: *mut VMContext) { - panic!("Dummy engine can't generate functions") -} - -extern "C" fn dummy_trampoline( - _context: *mut VMContext, - _callee: *const VMFunctionBody, - _values: *mut u128, -) { - panic!("Dummy engine can't generate trampolines") -} - -impl DummyArtifact { - const MAGIC_HEADER: &'static [u8] = b"\0wasmer-dummy"; - - /// Check if the provided bytes look like a serialized `DummyArtifact`. - pub fn is_deserializable(bytes: &[u8]) -> bool { - bytes.starts_with(Self::MAGIC_HEADER) - } - - #[cfg(feature = "compiler")] - /// Compile a data buffer into a `DummyArtifact`, which may then be instantiated. - pub fn new( - engine: &DummyEngine, - data: &[u8], - tunables: &dyn Tunables, - ) -> Result { - let environ = ModuleEnvironment::new(); - - let translation = environ.translate(data).map_err(CompileError::Wasm)?; - - let memory_styles: PrimaryMap = translation - .module - .memories - .values() - .map(|memory_type| tunables.memory_style(memory_type)) - .collect(); - let table_styles: PrimaryMap = translation - .module - .tables - .values() - .map(|table_type| tunables.table_style(table_type)) - .collect(); - - let data_initializers = translation - .data_initializers - .iter() - .map(OwnedDataInitializer::new) - .collect::>() - .into_boxed_slice(); - - let metadata = DummyArtifactMetadata { - module: Arc::new(translation.module), - features: Features::default(), - data_initializers, - memory_styles, - table_styles, - cpu_features: engine.target().cpu_features().as_u64(), - }; - Self::from_parts(engine, metadata) - } - - #[cfg(not(feature = "compiler"))] - pub fn new(engine: &DummyEngine, data: &[u8]) -> Result { - CompileError::Generic("The compiler feature is not enabled in the DummyEngine") - } - - #[cfg(feature = "serialize")] - /// Deserialize a DummyArtifact - pub fn deserialize(engine: &DummyEngine, bytes: &[u8]) -> Result { - if !Self::is_deserializable(bytes) { - return Err(DeserializeError::Incompatible( - "The provided bytes are not of the dummy engine".to_string(), - )); - } - - let inner_bytes = &bytes[Self::MAGIC_HEADER.len()..]; - - let metadata: DummyArtifactMetadata = bincode::deserialize(inner_bytes) - .map_err(|e| DeserializeError::CorruptedBinary(format!("{:?}", e)))?; - - Self::from_parts(engine, metadata).map_err(DeserializeError::Compiler) - } - - #[cfg(not(feature = "serialize"))] - pub fn deserialize(engine: &DummyEngine, bytes: &[u8]) -> Result { - Err(DeserializeError::Generic( - "The serializer feature is not enabled in the DummyEngine", - )) - } - - /// Construct a `DummyArtifact` from component parts. - pub fn from_parts( - engine: &DummyEngine, - metadata: DummyArtifactMetadata, - ) -> Result { - let num_local_functions = - metadata.module.functions.len() - metadata.module.num_imported_functions; - // We prepare the pointers for the finished functions. - let finished_functions: PrimaryMap = (0 - ..num_local_functions) - .map(|_| FunctionBodyPtr(dummy_function as _)) - .collect::>(); - - // We prepare the pointers for the finished function call trampolines. - let finished_function_call_trampolines: PrimaryMap = (0 - ..metadata.module.signatures.len()) - .map(|_| dummy_trampoline as VMTrampoline) - .collect::>(); - - // We prepare the pointers for the finished dynamic function trampolines. - let finished_dynamic_function_trampolines: PrimaryMap = (0 - ..metadata.module.num_imported_functions) - .map(|_| FunctionBodyPtr(dummy_function as _)) - .collect::>(); - - // Compute indices into the shared signature table. - let signatures = { - metadata - .module - .signatures - .values() - .map(|sig| engine.register_signature(sig)) - .collect::>() - }; - - let finished_functions = finished_functions.into_boxed_slice(); - let finished_function_call_trampolines = - finished_function_call_trampolines.into_boxed_slice(); - let finished_dynamic_function_trampolines = - finished_dynamic_function_trampolines.into_boxed_slice(); - let signatures = signatures.into_boxed_slice(); - - Ok(Self { - metadata, - finished_functions, - finished_function_call_trampolines, - finished_dynamic_function_trampolines, - signatures, - func_data_registry: engine.func_data().clone(), - }) - } -} - -impl ArtifactCreate for DummyArtifact { - fn module(&self) -> Arc { - self.metadata.module.clone() - } - - fn module_ref(&self) -> &ModuleInfo { - &self.metadata.module - } - - fn module_mut(&mut self) -> Option<&mut ModuleInfo> { - Arc::get_mut(&mut self.metadata.module) - } - - fn features(&self) -> &Features { - &self.metadata.features - } - - fn cpu_features(&self) -> EnumSet { - EnumSet::from_u64(self.metadata.cpu_features) - } - - fn data_initializers(&self) -> &[OwnedDataInitializer] { - &*self.metadata.data_initializers - } - - fn memory_styles(&self) -> &PrimaryMap { - &self.metadata.memory_styles - } - - fn table_styles(&self) -> &PrimaryMap { - &self.metadata.table_styles - } - #[cfg(feature = "serialize")] - fn serialize(&self) -> Result, SerializeError> { - let bytes = bincode::serialize(&self.metadata) - .map_err(|e| SerializeError::Generic(format!("{:?}", e)))?; - - // Prepend the header. - let mut serialized = Self::MAGIC_HEADER.to_vec(); - serialized.extend(bytes); - Ok(serialized) - } - - #[cfg(not(feature = "serialize"))] - fn serialize(&self) -> Result, SerializeError> { - Err(SerializeError::Generic( - "The serializer feature is not enabled in the DummyEngine", - )) - } -} -impl Artifact for DummyArtifact { - fn register_frame_info(&self) { - // Do nothing, since functions are not generated for the dummy engine - } - - fn finished_functions(&self) -> &BoxedSlice { - &self.finished_functions - } - - fn finished_function_call_trampolines(&self) -> &BoxedSlice { - &self.finished_function_call_trampolines - } - - fn finished_dynamic_function_trampolines(&self) -> &BoxedSlice { - &self.finished_dynamic_function_trampolines - } - - fn signatures(&self) -> &BoxedSlice { - &self.signatures - } - - fn func_data_registry(&self) -> &FuncDataRegistry { - &self.func_data_registry - } -} diff --git a/tests/lib/engine-dummy/src/engine.rs b/tests/lib/engine-dummy/src/engine.rs deleted file mode 100644 index 831049e68b0..00000000000 --- a/tests/lib/engine-dummy/src/engine.rs +++ /dev/null @@ -1,129 +0,0 @@ -//! Dummy Engine. - -use crate::DummyArtifact; -use std::sync::Arc; -use wasmer_compiler::{CompileError, Features, Target}; -use wasmer_engine::{Artifact, DeserializeError, Engine, EngineId, Tunables}; -use wasmer_types::FunctionType; -use wasmer_vm::{ - FuncDataRegistry, SignatureRegistry, VMCallerCheckedAnyfunc, VMContext, VMFuncRef, - VMFunctionBody, VMSharedSignatureIndex, -}; - -#[allow(dead_code)] -extern "C" fn dummy_trampoline( - _context: *mut VMContext, - _body: *const VMFunctionBody, - _values: *mut u128, -) { - panic!("Dummy engine can't call functions, since Wasm function bodies are not really compiled") -} - -/// A WebAssembly `Dummy` Engine. -#[derive(Clone)] -#[cfg_attr(feature = "compiler", derive(Default))] -pub struct DummyEngine { - signatures: Arc, - func_data: Arc, - features: Arc, - target: Arc, - engine_id: EngineId, -} - -impl DummyEngine { - #[cfg(feature = "compiler")] - pub fn new() -> Self { - Default::default() - } - - pub fn features(&self) -> &Features { - &self.features - } - - /// Shared func metadata registry. - pub(crate) fn func_data(&self) -> &Arc { - &self.func_data - } -} - -impl Engine for DummyEngine { - /// Get the tunables - fn target(&self) -> &Target { - &self.target - } - - /// Register a signature - fn register_signature(&self, func_type: &FunctionType) -> VMSharedSignatureIndex { - self.signatures.register(func_type) - } - - fn register_function_metadata(&self, func_data: VMCallerCheckedAnyfunc) -> VMFuncRef { - self.func_data.register(func_data) - } - - /// Lookup a signature - fn lookup_signature(&self, sig: VMSharedSignatureIndex) -> Option { - self.signatures.lookup(sig) - } - - #[cfg(feature = "compiler")] - /// Validates a WebAssembly module - fn validate(&self, binary: &[u8]) -> Result<(), CompileError> { - use wasmer_compiler::wasmparser::{Validator, WasmFeatures}; - - let features = self.features(); - let mut validator = Validator::new(); - let wasm_features = WasmFeatures { - bulk_memory: features.bulk_memory, - threads: features.threads, - reference_types: features.reference_types, - multi_value: features.multi_value, - simd: features.simd, - tail_call: features.tail_call, - module_linking: features.module_linking, - multi_memory: features.multi_memory, - memory64: features.memory64, - exceptions: features.exceptions, - deterministic_only: false, - extended_const: features.extended_const, - relaxed_simd: features.relaxed_simd, - mutable_global: true, - saturating_float_to_int: true, - sign_extension: true, - }; - validator.wasm_features(wasm_features); - validator - .validate_all(binary) - .map_err(|e| CompileError::Validate(format!("{}", e)))?; - Ok(()) - } - - #[cfg(not(feature = "compiler"))] - /// Validates a WebAssembly module - fn validate(&self, binary: &[u8]) -> Result<(), CompileError> { - // We mark all Wasm modules as valid - Ok(()) - } - - /// Compile a WebAssembly binary - fn compile( - &self, - binary: &[u8], - tunables: &dyn Tunables, - ) -> Result, CompileError> { - Ok(Arc::new(DummyArtifact::new(self, binary, tunables)?)) - } - - /// Deserializes a WebAssembly module (binary content of a Shared Object file) - unsafe fn deserialize(&self, bytes: &[u8]) -> Result, DeserializeError> { - Ok(Arc::new(DummyArtifact::deserialize(self, bytes)?)) - } - - fn id(&self) -> &EngineId { - &self.engine_id - } - - fn cloned(&self) -> Arc { - Arc::new(self.clone()) - } -} diff --git a/tests/lib/engine-dummy/src/lib.rs b/tests/lib/engine-dummy/src/lib.rs deleted file mode 100644 index ed7e39b95e2..00000000000 --- a/tests/lib/engine-dummy/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod artifact; -mod engine; - -pub use artifact::DummyArtifact; -pub use engine::DummyEngine; diff --git a/tests/lib/test-generator/Cargo.toml b/tests/lib/test-generator/Cargo.toml index 4b4886bb75b..0374ef83ce8 100644 --- a/tests/lib/test-generator/Cargo.toml +++ b/tests/lib/test-generator/Cargo.toml @@ -10,5 +10,4 @@ anyhow = "1.0" target-lexicon = "0.12" [features] -test-dylib = [] test-universal = []