Merge remote-tracking branch 'origin/master' into wasix

This commit is contained in:
Christoph Herzog
2022-12-13 01:40:22 +01:00
54 changed files with 1566 additions and 1559 deletions

View File

@@ -9,74 +9,102 @@ Looking for changes that affect our C API? See the [C API Changelog](lib/c-api/C
## **Unreleased**
## 3.1.0 - 12/12/2022
## Added
- [#3403](https://github.com/wasmerio/wasmer/pull/3403) Add wasm_importtype_copy to C API
## Changed
- [#3416](https://github.com/wasmerio/wasmer/pull/3416) Download and install packages via .tar.gz URLs and improve installation error message
- [#3402](https://github.com/wasmerio/wasmer/pull/3402) Do not run first command of wapm file and print all commands instead
- [#3400](https://github.com/wasmerio/wasmer/pull/3400) Use the wasm_bindgen_downcast crate for downcasting JsValues
- [#3363](https://github.com/wasmerio/wasmer/pull/3363) Store Used CpuFeature in Artifact instead of Present CpuFeatures for Singlepass
- [#3378](https://github.com/wasmerio/wasmer/pull/3378) Introduced EngineRef and AsEngineRef trait
- [#3386](https://github.com/wasmerio/wasmer/pull/3386) Restore Support For All Wasi Clock Types
- [#3153](https://github.com/wasmerio/wasmer/pull/3153) SharedMemory & Atomics
## Fixed
- [#3415](https://github.com/wasmerio/wasmer/pull/3415) Fix singlepass for Aarch64
- [#3395](https://github.com/wasmerio/wasmer/pull/3395) Fix create-exe to be able to cross-compile on Windows
- [#3396](https://github.com/wasmerio/wasmer/pull/3396) Fix build doc and minimum-sys build
## 3.0.2 - 25/11/2022
## Added
- [#3364](https://github.com/wasmerio/wasmer/pull/3364) Added the actual LZCNT / TZCNT implementation
- [#3361](https://github.com/wasmerio/wasmer/pull/3361) Give users feedback when they are running "wasmer add ..."
## Changed
- [#3365](https://github.com/wasmerio/wasmer/pull/3365) Improve FreeBSD support
- [#3368](https://github.com/wasmerio/wasmer/pull/3368) Remove wasi conditional compilation from wasmer-registry
- [#3367](https://github.com/wasmerio/wasmer/pull/3367) Change LLVM detection in Makefile
- [#3365](https://github.com/wasmerio/wasmer/pull/3365) Improve FreeBSD support
- [#3360](https://github.com/wasmerio/wasmer/pull/3360) Introduce a "wasmer_registry::queries" module with all GraphQL queries
## Fixed
- [#3371](https://github.com/wasmerio/wasmer/pull/3371) Fix cargo binstall
- [#3370](https://github.com/wasmerio/wasmer/pull/3370) Fix wasmer run not interpreting URLs correctly + display fixes
- [#3371](https://github.com/wasmerio/wasmer/pull/3371) Fix cargo binstall
## 3.0.1 - 23/11/2022
## Added
- [#3361](https://github.com/wasmerio/wasmer/pull/3361) Give users feedback when they are running "wasmer add ..."
## Changed
- [#3360](https://github.com/wasmerio/wasmer/pull/3360) Introduce a "wasmer_registry::queries" module with all GraphQL queries
- [#3355](https://github.com/wasmerio/wasmer/pull/3355) Fetch the pirita download URL
- [#3344](https://github.com/wasmerio/wasmer/pull/3344) Revert #3145
- [#3302](https://github.com/wasmerio/wasmer/pull/3302) Some Refactor of Singlepass compiler to have better error and cpu features handling
- [#3296](https://github.com/wasmerio/wasmer/pull/3296) Use the right collection when parsing type section
- [#3292](https://github.com/wasmerio/wasmer/pull/3292) Precompute offsets in VMOffsets
- [#3290](https://github.com/wasmerio/wasmer/pull/3290) Limit the use of clone when handling Compilation object
- [#3316](https://github.com/wasmerio/wasmer/pull/3316) Implement wasmer whoami
- [#3341](https://github.com/wasmerio/wasmer/pull/3341) Update CHANGELOG.md
## Fixed
- [#3342](https://github.com/wasmerio/wasmer/pull/3342) Fixes for 3.0.0 release
## 3.0.0 - 20/11/2022
## Added
- [#3338](https://github.com/wasmerio/wasmer/3338) Re-add codecov to get coverage reports
- [#3337](https://github.com/wasmerio/wasmer/3337) Add automation script to automate deploying releases on GitHub
- [#3339](https://github.com/wasmerio/wasmer/pull/3339) Fixes for wasmer login / wasmer add
- [#3337](https://github.com/wasmerio/wasmer/pull/3337) Add automation script to automate deploying releases on GitHub
- [#3338](https://github.com/wasmerio/wasmer/pull/3338) Re-add codecov to get coverage reports
## Changed
- [#3295](https://github.com/wasmerio/wasmer/pull/3295) Implement wasmer run {url}
## Fixed
- [#3339](https://github.com/wasmerio/wasmer/3339) Fixes for wasmer login / wasmer add
## 3.0.0-rc.3 - 2022/11/18
## Added
- [#3314](https://github.com/wasmerio/wasmer/pull/3314) Add windows-gnu workflow
- [#3317](https://github.com/wasmerio/wasmer/pull/3317) Add a `wasmer add` command for adding bindings to a WAPM package
- [#3297](https://github.com/wasmerio/wasmer/pull/3297) Implement wasmer login
- [#3311](https://github.com/wasmerio/wasmer/pull/3311) Export `Module::IoCompileError`
## Changed
- [#3319](https://github.com/wasmerio/wasmer/pull/3319) Disable 'Test integration CLI' on CI for the Windows platform as it's not working at all
- [#3317](https://github.com/wasmerio/wasmer/pull/3317) Port "wapm install" to Wasmer
- [#3318](https://github.com/wasmerio/wasmer/pull/3318) Bump the MSRV to 1.63
- [#3319](https://github.com/wasmerio/wasmer/pull/3319) Disable 'Test integration CLI' on CI for the Windows platform as it's not working at all
- [#3297](https://github.com/wasmerio/wasmer/pull/3297) Implement wasmer login
- [#3311](https://github.com/wasmerio/wasmer/pull/3311) Export Module::IoCompileError as it's an error returned by an exported function
- [#2800](https://github.com/wasmerio/wasmer/pull/2800) RISC-V support
- [#3293](https://github.com/wasmerio/wasmer/pull/3293) Removed call to to_vec() on assembler.finalise()
- [#3288](https://github.com/wasmerio/wasmer/pull/3288) Rollback all the TARGET_DIR changes
- [#3284](https://github.com/wasmerio/wasmer/pull/3284) Makefile now handle TARGET_DIR env. var. for build too
- [#3276](https://github.com/wasmerio/wasmer/pull/3276) Remove unnecessary checks to test internet connection
- [#3266](https://github.com/wasmerio/wasmer/pull/3266) Return ENotCapable error when accessing unknown files on root (for #3263 and #3264)
- [#3275](https://github.com/wasmerio/wasmer/pull/3275) Disable printing "local package ... not found" in release mode
- [#3273](https://github.com/wasmerio/wasmer/pull/3273) Undo Makefile commit
@@ -89,155 +117,177 @@ Looking for changes that affect our C API? See the [C API Changelog](lib/c-api/C
- [#3285](https://github.com/wasmerio/wasmer/pull/3285) Fix CI to setup TARGET_DIR to target/release directly
- [#3277](https://github.com/wasmerio/wasmer/pull/3277) Fix red CI on master
## 3.0.0-rc.2 - 2022/11/02
## Added
## Changed
- [#3258](https://github.com/wasmerio/wasmer/pull/3258) Migrate pirita / native executables feature from wasmer-private
## Fixed
- [#3268](https://github.com/wasmerio/wasmer/pulls/3268) Fix fd_right nightly test to avoid foo.txt file leftover
- [#3260](https://github.com/wasmerio/wasmer/pulls/3260) Fix bug in wasmer run
- [#3257](https://github.com/wasmerio/wasmer/pulls/3257) Fix linux-aarch64 build
- [#3268](https://github.com/wasmerio/wasmer/pull/3268) Fix fd_right nightly test to avoid foo.txt file leftover
- [#3260](https://github.com/wasmerio/wasmer/pull/3260) Fix bug in wasmer run
- [#3257](https://github.com/wasmerio/wasmer/pull/3257) Fix linux-aarch64 build
## 3.0.0-rc.1 - 2022/10/25
## Added
- [#3215](https://github.com/wasmerio/wasmer/pull/3215) Update wasmer --version logic, integrate wapm-cli
- [#3218](https://github.com/wasmerio/wasmer/pull/3218) Seal `HostFunctionKind`
- [#3222](https://github.com/wasmerio/wasmer/pull/3222) Add function to retrieve function name from wasm_frame_t
- [#3240](https://github.com/wasmerio/wasmer/pull/3240) Fix filesystem rights on WASI, add integration test for file permissions
- [#3238](https://github.com/wasmerio/wasmer/pull/3238) Fixed main README ocaml homepage link and added ocaml in other language README
- [#3145](https://github.com/wasmerio/wasmer/pull/3145) C-API: add functions to overwrite stdin / stdout / stderr handlers
## Changed
- [#3215](https://github.com/wasmerio/wasmer/pull/3215) Update wasmer --version logic, integrate wapm-cli
- [#3248](https://github.com/wasmerio/wasmer/pull/3248) Move loupe CHANGELOG entry from 2.3.0 to 3.x
- [#3230](https://github.com/wasmerio/wasmer/pull/3230) Remove test if dest file exist on path_rename wasi syscall (for #3228)
- [#3061](https://github.com/wasmerio/wasmer/pull/3061) Removed trailing zero in WASI::fd_prestat_dir_name name return (for #3025)
- [#3223](https://github.com/wasmerio/wasmer/pull/3223) Delete lib/wasi-types-generated directory
- [#3178](https://github.com/wasmerio/wasmer/pull/3178) Feat enhanced tinytunable test
- [#3177](https://github.com/wasmerio/wasmer/pull/3177) Auto-generate wasi-types from .wit files
- [#3218](https://github.com/wasmerio/wasmer/pull/3218) Seal `HostFunctionKind`
## Fixed
- [#3145](https://github.com/wasmerio/wasmer/pull/3145) C-API: add functions to overwrite stdin / stdout / stderr handlers
- [#3240](https://github.com/wasmerio/wasmer/pull/3240) Fix filesystem rights on WASI, add integration test for file permissions
- [#3238](https://github.com/wasmerio/wasmer/pull/3238) Fixed main README ocaml homepage link and added ocaml in other language README
- [#3221](https://github.com/wasmerio/wasmer/pull/3221) Fix #3197
- [#3229](https://github.com/wasmerio/wasmer/pull/3229) Fixed version to nightly-2022-10-09 for the CI build Minimal Wasmer Headless again
- [#3227](https://github.com/wasmerio/wasmer/pull/3227) Fixed version to nightly-2022-10-09 for the CI build Minimal Wasmer Headless
- [#3226](https://github.com/wasmerio/wasmer/pull/3226) Fixed version to nightly-2002-10-09 for the CI build Minimal Wasmer Headless
- [#3221](https://github.com/wasmerio/wasmer/pull/3221) Fix #3197
- [#3211](https://github.com/wasmerio/wasmer/pull/3211) Fix popcnt for aarch64
- [#3211](https://github.com/wasmerio/wasmer/pull/3211) fix popcnt for aarch64
- [#3204](https://github.com/wasmerio/wasmer/pull/3204) Fixed a typo in README
- [#3199](https://github.com/wasmerio/wasmer/pull/3199) Release fixes
## 3.0.0-beta.2 - 2022/09/26
## Added
- [#3176](https://github.com/wasmerio/wasmer/pull/3176) Add support for `cargo-binstall`
- [#3141](https://github.com/wasmerio/wasmer/pull/3141) The API breaking changes from future WASIX/Network/Threading addition
- [#3119](https://github.com/wasmerio/wasmer/pull/3119) Added LinearMemory trait
- [#3117](https://github.com/wasmerio/wasmer/pull/3117) Add tests for wasmer-cli create-{exe,obj} commands
- [#3116](https://github.com/wasmerio/wasmer/pull/3116) Multithreading, full networking and RPC for WebAssembly
- [#3101](https://github.com/wasmerio/wasmer/pull/3101) CI/build.yaml: add libwasmer headless in default distribution
- [#3090](https://github.com/wasmerio/wasmer/pull/3090) Added version to the wasmer cli
- [#3089](https://github.com/wasmerio/wasmer/pull/3089) Add wasi_* C-API function changes in migration guide for 3.0.0
- [#3076](https://github.com/wasmerio/wasmer/pull/3076) Add support for cross-compiling in create-exe with zig cc WIP
- [#3072](https://github.com/wasmerio/wasmer/pull/3072) Add back `Function::*_with_env(…)`
- [#3048](https://github.com/wasmerio/wasmer/pull/3048) Add cloudcompiler.yaml
- [#3068](https://github.com/wasmerio/wasmer/pull/3068) create-{exe,obj}: add documentations and header file generation for create-obj
- [#3065](https://github.com/wasmerio/wasmer/pull/3065) Added '.' and '..' special folder t WASI fd_readdir return (for #3033)
## Changed
- [#3165](https://github.com/wasmerio/wasmer/pull/3165) Initial port of make test-js-core (port wasmer API to core)
- [#3184](https://github.com/wasmerio/wasmer/pull/3184) Test libwasmer.dll on Windows
- [#3164](https://github.com/wasmerio/wasmer/pull/3164) Synchronize between -sys and -js tests
- [#3142](https://github.com/wasmerio/wasmer/pull/3142) Bump rust toolchain
- [#3141](https://github.com/wasmerio/wasmer/pull/3141) The API breaking changes from future WASIX/Network/Threading addition
- [#3165](https://github.com/wasmerio/wasmer/pull/3165) Initial port of make test-js-core (port wasmer API to core)
- [#3138](https://github.com/wasmerio/wasmer/pull/3138) Js imports revamp
- [#3134](https://github.com/wasmerio/wasmer/pull/3134) Bring libwasmer-headless.a from 22MiB to 7.2MiB (on my machine)
- [#3132](https://github.com/wasmerio/wasmer/pull/3132) Revert "Lower libwasmer headless size"
- [#3131](https://github.com/wasmerio/wasmer/pull/3131) Update for migration-to-3.0.0 for MemoryView changes
- [#3142](https://github.com/wasmerio/wasmer/pull/3142) Bump rust toolchain
- [#3116](https://github.com/wasmerio/wasmer/pull/3116) Multithreading, full networking and RPC for WebAssembly
- [#3130](https://github.com/wasmerio/wasmer/pull/3130) Remove panics from Artifact::deserialize
- [#3134](https://github.com/wasmerio/wasmer/pull/3134) Bring libwasmer-headless.a from 22MiB to 7.2MiB (on my machine)
- [#3131](https://github.com/wasmerio/wasmer/pull/3131) Update for migration-to-3.0.0 for MemoryView changes
- [#3123](https://github.com/wasmerio/wasmer/pull/3123) Lower libwasmer headless size
- [#3132](https://github.com/wasmerio/wasmer/pull/3132) Revert "Lower libwasmer headless size"
- [#3128](https://github.com/wasmerio/wasmer/pull/3128) scripts/publish.py: validate crates version before publishing
- [#3126](https://github.com/wasmerio/wasmer/pull/3126) scripts/publish.py: replace toposort dependency with python std graphlib module
- [#3123](https://github.com/wasmerio/wasmer/pull/3123) Lower libwasmer headless size
- [#3122](https://github.com/wasmerio/wasmer/pull/3122) Update Cargo.lock dependencies
- [#3119](https://github.com/wasmerio/wasmer/pull/3119) Added LinearMemory trait
- [#3118](https://github.com/wasmerio/wasmer/pull/3118) Refactor Artifact enum into a struct
- [#3114](https://github.com/wasmerio/wasmer/pull/3114) Implemented shared memory for Wasmer in preparation for multithreading
- [#3104](https://github.com/wasmerio/wasmer/pull/3104) Re-enabled ExternRef tests
- [#3103](https://github.com/wasmerio/wasmer/pull/3103) create-exe: prefer libwasmer headless when cross-compiling
- [#3097](https://github.com/wasmerio/wasmer/pull/3097) MemoryView lifetime tied to memory and not StoreRef
- [#3096](https://github.com/wasmerio/wasmer/pull/3096) create-exe: use cached wasmer tarballs for network fetches
- [#3095](https://github.com/wasmerio/wasmer/pull/3095) create-exe: list supported cross-compilation target triples in help …
- [#3096](https://github.com/wasmerio/wasmer/pull/3096) create-exe: use cached wasmer tarballs for network fetches
- [#3083](https://github.com/wasmerio/wasmer/pull/3083) Disable wasm build in build CI
- [#3081](https://github.com/wasmerio/wasmer/pull/3081) 3.0.0-beta release
- [#3079](https://github.com/wasmerio/wasmer/pull/3079) Migrate to clap from structopt
- [#3075](https://github.com/wasmerio/wasmer/pull/3075) Remove __wbindgen_thread_id
- [#3074](https://github.com/wasmerio/wasmer/pull/3074) Update chrono to 0.4.20, avoiding RUSTSEC-2020-0159
- [#3070](https://github.com/wasmerio/wasmer/pull/3070) wasmer-cli: Allow create-exe to receive a static object as input
- [#3069](https://github.com/wasmerio/wasmer/pull/3069) Remove native feature entry from docs.rs metadata
- [#3057](https://github.com/wasmerio/wasmer/pull/3057) wasmer-cli: create-obj command
- [#3060](https://github.com/wasmerio/wasmer/pull/3060) CI: Unset rustup override after usage instead of setting it to stable
## Fixed
- [#3192](https://github.com/wasmerio/wasmer/pull/3192) fix the typos
- [#3185](https://github.com/wasmerio/wasmer/pull/3185) Fix `wasmer compile` command for non-x86 target
- [#3184](https://github.com/wasmerio/wasmer/pull/3184) Fix windows build
- [#3137](https://github.com/wasmerio/wasmer/pull/3137) Fix cache path not being present during installation of cross-tarball
- [#3129](https://github.com/wasmerio/wasmer/pull/3129) Fix differences between -sys and -js API
- [#3137](https://github.com/wasmerio/wasmer/pull/3137) Fix cache path not being present during installation of cross-tarball
- [#3115](https://github.com/wasmerio/wasmer/pull/3115) Fix static object signature deserialization
- [#3093](https://github.com/wasmerio/wasmer/pull/3093) Fixed a potential issue when renaming a file
- [#3088](https://github.com/wasmerio/wasmer/pull/3088) Fixed an issue when renaming a file from a preopened dir directly (for 3084)
- [#3078](https://github.com/wasmerio/wasmer/pull/3078) Fix errors from "make lint"
- [#3052](https://github.com/wasmerio/wasmer/pull/3052) Fixed a memory corruption issue with JS memory operations that were r…
- [#3058](https://github.com/wasmerio/wasmer/pull/3058) Fix trap tracking
## 3.0.0-beta - 2022/08/08
### Added
- [#3076](https://github.com/wasmerio/wasmer/pull/3076) Add support for cross-compiling in create-exe with zig cc
### Changed
- [#3079](https://github.com/wasmerio/wasmer/pull/3079) Migrate CLI tools to `clap` from `structopt`
- [#3048](https://github.com/wasmerio/wasmer/pull/3048) Automatically publish wasmer as "cloudcompiler" package to wapm.dev on every release
- [#3075](https://github.com/wasmerio/wasmer/pull/3075) Remove __wbindgen_thread_id
- [#3072](https://github.com/wasmerio/wasmer/pull/3072) Add back `Function::*_with_env(…)` functions
### Fixed
## 3.0.0-alpha.4 - 2022/07/28
### Added
- [#3035](https://github.com/wasmerio/wasmer/pull/3035) Added a simple "divide by zero" wast test, for #1899, as the trap information are correctly tracked on singlepass now
- [#3021](https://github.com/wasmerio/wasmer/pull/3021) Add back missing Aarch64 relocations (needed for llvm compiler)
- [#3008](https://github.com/wasmerio/wasmer/pull/3008) Add a new cargo public-api CI check
- [#2941](https://github.com/wasmerio/wasmer/pull/2941) Implementation of WASIX and a fully networking for Web Assembly
- [#2952](https://github.com/wasmerio/wasmer/pull/2952) CI: add make build-wasmer-wasm test
- [#2982](https://github.com/wasmerio/wasmer/pull/2982) Add a rustfmt.toml file to the repository
## Added
### Changed
- [#3047](https://github.com/wasmerio/wasmer/pull/3047) `Store::new` now takes an `impl Into<Engine>`.
- [#3035](https://github.com/wasmerio/wasmer/pull/3035) Added a simple divide by zero trap wast test (for #1899)
- [#3008](https://github.com/wasmerio/wasmer/pull/3008) Add check-public-api.yaml workflow
- [#3021](https://github.com/wasmerio/wasmer/pull/3021) Added back some needed relocation for arm64 llvm compiler
- [#2982](https://github.com/wasmerio/wasmer/pull/2982) Add a `rustfmt.toml` file to the repository
- [#2953](https://github.com/wasmerio/wasmer/pull/2953) Makefile: add `check` target
- [#2952](https://github.com/wasmerio/wasmer/pull/2952) CI: add make build-wasmer-wasm test
## Changed
- [#3051](https://github.com/wasmerio/wasmer/pull/3051) Updated Crenelift to v0.86.1
- [#3038](https://github.com/wasmerio/wasmer/pull/3038) Re-introduce create-exe to wasmer-cli v3.0
- [#3049](https://github.com/wasmerio/wasmer/pull/3049) Disable traps::trap_display_multi_module test for Windows+singlepass
- [#3047](https://github.com/wasmerio/wasmer/pull/3047) Improved EngineBuilder API
- [#3046](https://github.com/wasmerio/wasmer/pull/3046) Merge Backend into EngineBuilder and refactor feature flags
- [#3039](https://github.com/wasmerio/wasmer/pull/3039) Improved hashing/ids of function envs
- [#3029](https://github.com/wasmerio/wasmer/pull/3029) Remove Engine, Artifact traits, merge all Engines into one, make everything rkyv serialazable
- [#2892](https://github.com/wasmerio/wasmer/pull/2892) Implement new Context API for Wasmer 3.0
- [#3031](https://github.com/wasmerio/wasmer/pull/3031) Update docs/migration_to_3.0.0.md
- [#3030](https://github.com/wasmerio/wasmer/pull/3030) Remove cranelift dependency from wasmer-wasi
- [#3029](https://github.com/wasmerio/wasmer/pull/3029) Removed Artifact, Engine traits. Renamed UniversalArtifact to Artifact, and UniversalEngine to Engine.
- [#3028](https://github.com/wasmerio/wasmer/pull/3028) Rename old variable names from ctx to env (in case of FunctionEnv usage) and from ctx to store in case of store usage
- [#3023](https://github.com/wasmerio/wasmer/pull/3023) Changed CI "rust install" action to dtolnay one
- [#3013](https://github.com/wasmerio/wasmer/pull/3013) Refactor Context API
- [#3028](https://github.com/wasmerio/wasmer/pull/3028) Ctx store rename
- [#3023](https://github.com/wasmerio/wasmer/pull/3023) Changed CI rust install action to dtolnay one
- [#3013](https://github.com/wasmerio/wasmer/pull/3013) Context api refactor
- [#2999](https://github.com/wasmerio/wasmer/pull/2999) Support --invoke option for emscripten files without _start function
- [#3003](https://github.com/wasmerio/wasmer/pull/3003) Remove RuntimeError::raise from public API
- [#3000](https://github.com/wasmerio/wasmer/pull/3001) Allow debugging of EXC_BAD_INSTRUCTION on macOS
- [#2999](https://github.com/wasmerio/wasmer/pull/2999) Allow `--invoke` CLI option for Emscripten files without a `main` function
- [#2996](https://github.com/wasmerio/wasmer/pull/2996) Migrated all examples to new Context API
- [#2946](https://github.com/wasmerio/wasmer/pull/2946) Remove dylib,staticlib engines in favor of a single Universal engine
- [#2949](https://github.com/wasmerio/wasmer/pull/2949) Switch back to using custom LLVM builds on CI
- [#2892](https://github.com/wasmerio/wasmer/pull/2892) Renamed `get_native_function` to `get_typed_function`, marked former as deprecated.
- [#2976](https://github.com/wasmerio/wasmer/pull/2976) Upgrade enumset minimum version to one that compiles
- [#2974](https://github.com/wasmerio/wasmer/pull/2974) Context api tests
- [#3000](https://github.com/wasmerio/wasmer/pull/3000) Allow debugging of EXC_BAD_INSTRUCTION on macOS
- [#2946](https://github.com/wasmerio/wasmer/pull/2946) Removing dylib and staticlib engines in favor of a single Universal Engine
- [#2996](https://github.com/wasmerio/wasmer/pull/2996) Migrated al examples to new Context API
- [#2973](https://github.com/wasmerio/wasmer/pull/2973) Port C API to new Context API
- [#2969](https://github.com/wasmerio/wasmer/pull/2969) Port JS API to new Context API
- [#2966](https://github.com/wasmerio/wasmer/pull/2966) Singlepass nopanic #2966
- [#2957](https://github.com/wasmerio/wasmer/pull/2957) Enable multi-value handling in Singlepass compiler
- [#2954](https://github.com/wasmerio/wasmer/pull/2954) Some fixes to x86_64 Singlepass compiler, when using atomics
- [#2953](https://github.com/wasmerio/wasmer/pull/2953) Makefile: add check target
- [#2950](https://github.com/wasmerio/wasmer/pull/2950) compiler-cranelift: Fix typo in enum variant
- [#2947](https://github.com/wasmerio/wasmer/pull/2947) Converted the WASI js test into a generic stdio test that works for both sys and js versions of wasmer
- [#2940](https://github.com/wasmerio/wasmer/pull/2940) Merge wasmer3 back to master branch
- [#2939](https://github.com/wasmerio/wasmer/pull/2939) Rename NativeFunc to TypedFunction
- [#2868](https://github.com/wasmerio/wasmer/pull/2868) Removed loupe crate dependency
### Fixed
- [#3045](https://github.com/wasmerio/wasmer/pull/3045) Fixed WASI fd_read syscall when reading multiple iovs and read is partial (for #2904)
- [#3027](https://github.com/wasmerio/wasmer/pull/3027) Fixed some residual doc issues that prevented make package-docs to build
- [#3026](https://github.com/wasmerio/wasmer/pull/3026) test-js.yaml: fix typo
- [#3017](https://github.com/wasmerio/wasmer/pull/3017) Fix typo in README.md
- [#3001](https://github.com/wasmerio/wasmer/pull/3001) Fix context capi ci errors
- [#2997](https://github.com/wasmerio/wasmer/pull/2997) Fix "run --invoke [function]" to behave the same as "run"
- [#2963](https://github.com/wasmerio/wasmer/pull/2963) Remove accidental dependency on libwayland and libxcb in ClI
- [#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
- [#2976](https://github.com/wasmerio/wasmer/pull/2976) Upgrade minimum enumset to one that compiles
- [#2974](https://github.com/wasmerio/wasmer/pull/2974) Context api tests
- [#2988](https://github.com/wasmerio/wasmer/pull/2988) Have make targets install-capi-lib,install-pkgconfig work without building the wasmer binary
- [#2976](https://github.com/wasmerio/wasmer/pull/2976) Upgrade enumset minimum version to one that compiles
- [#2969](https://github.com/wasmerio/wasmer/pull/2969) Port JS API to new Context API
- [#2966](https://github.com/wasmerio/wasmer/pull/2966) Singlepass nopanic
- [#2949](https://github.com/wasmerio/wasmer/pull/2949) Switch back to using custom LLVM builds on CI
- [#2963](https://github.com/wasmerio/wasmer/pull/2963) Remove libxcb and libwayland dependencies from wasmer-cli release build
- [#2957](https://github.com/wasmerio/wasmer/pull/2957) Enable multi-value handling in Singlepass compiler
- [#2941](https://github.com/wasmerio/wasmer/pull/2941) Implementation of WASIX and a fully networking for Web Assembly
- [#2947](https://github.com/wasmerio/wasmer/pull/2947) - Converted the WASI js test into a generic stdio test that works for…
- [#2940](https://github.com/wasmerio/wasmer/pull/2940) Merge `wasmer3` back to `master` branch
- [#2939](https://github.com/wasmerio/wasmer/pull/2939) Rename NativeFunc to TypedFunction
## Fixed
- [#3045](https://github.com/wasmerio/wasmer/pull/3045) Fixed WASI fd_read syscall when reading multiple iovs and read is partial (for #2904)
- [#2997](https://github.com/wasmerio/wasmer/pull/2997) Fix "run --invoke [function]" to behave the same as "run"
- [#3027](https://github.com/wasmerio/wasmer/pull/3027) Fixed residual package-doc issues
- [#3026](https://github.com/wasmerio/wasmer/pull/3026) test-js.yaml: fix typo
- [#3017](https://github.com/wasmerio/wasmer/pull/3017) Fixed translation in README.md
- [#3001](https://github.com/wasmerio/wasmer/pull/3001) Fix context capi ci errors
- [#2967](https://github.com/wasmerio/wasmer/pull/2967) Fix singlepass on arm64 that was trying to emit a sub opcode with a constant as destination (for #2959)
- [#2954](https://github.com/wasmerio/wasmer/pull/2954) Some fixes to x86_64 Singlepass compiler, when using atomics
- [#2950](https://github.com/wasmerio/wasmer/pull/2950) compiler-cranelift: Fix typo in enum variant
- [#2948](https://github.com/wasmerio/wasmer/pull/2948) Fix regression on gen_import_call_trampoline_arm64()
- [#2943](https://github.com/wasmerio/wasmer/pull/2943) Fix build error on some archs by using c_char instead of i8
- [#2944](https://github.com/wasmerio/wasmer/pull/2944) Fix duplicate entries in the CHANGELOG
- [#2942](https://github.com/wasmerio/wasmer/pull/2942) Fix clippy lints
## 2.3.0 - 2022/06/06

95
Cargo.lock generated
View File

@@ -1101,9 +1101,9 @@ dependencies = [
[[package]]
name = "filetime"
version = "0.2.18"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3"
checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9"
dependencies = [
"cfg-if 1.0.0",
"libc",
@@ -1899,7 +1899,7 @@ dependencies = [
[[package]]
name = "macro-wasmer-universal-test"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"proc-macro2",
"proc-quote",
@@ -4076,7 +4076,7 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi-test-generator"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"glob",
"gumdrop",
@@ -4120,6 +4120,29 @@ dependencies = [
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-downcast"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340"
dependencies = [
"js-sys",
"once_cell",
"wasm-bindgen",
"wasm-bindgen-downcast-macros",
]
[[package]]
name = "wasm-bindgen-downcast-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.33"
@@ -4217,7 +4240,7 @@ dependencies = [
[[package]]
name = "wasmer"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"anyhow",
"bytes",
@@ -4235,6 +4258,7 @@ dependencies = [
"thiserror",
"tracing",
"wasm-bindgen",
"wasm-bindgen-downcast",
"wasm-bindgen-test",
"wasmer-compiler",
"wasmer-compiler-cranelift",
@@ -4266,7 +4290,7 @@ dependencies = [
[[package]]
name = "wasmer-c-api"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"cbindgen",
"cfg-if 1.0.0",
@@ -4294,7 +4318,7 @@ dependencies = [
[[package]]
name = "wasmer-c-api-test-runner"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"cc",
"regex",
@@ -4304,7 +4328,7 @@ dependencies = [
[[package]]
name = "wasmer-cache"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"blake3",
"criterion",
@@ -4318,7 +4342,7 @@ dependencies = [
[[package]]
name = "wasmer-capi-examples-runner"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"cc",
"regex",
@@ -4328,7 +4352,7 @@ dependencies = [
[[package]]
name = "wasmer-cli"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"anyhow",
"atty",
@@ -4341,6 +4365,7 @@ dependencies = [
"dirs",
"distance",
"fern",
"hex",
"http_req",
"isatty",
"libc",
@@ -4381,7 +4406,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"backtrace",
"cfg-if 1.0.0",
@@ -4407,7 +4432,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler-cli"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"anyhow",
"atty",
@@ -4429,7 +4454,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler-cranelift"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"cranelift-codegen",
"cranelift-entity",
@@ -4448,7 +4473,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler-llvm"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"byteorder",
"cc",
@@ -4470,7 +4495,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler-singlepass"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"byteorder",
"dynasm",
@@ -4489,7 +4514,7 @@ dependencies = [
[[package]]
name = "wasmer-derive"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"compiletest_rs",
"proc-macro-error",
@@ -4501,7 +4526,7 @@ dependencies = [
[[package]]
name = "wasmer-emscripten"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"byteorder",
"getrandom",
@@ -4543,7 +4568,7 @@ dependencies = [
[[package]]
name = "wasmer-integration-tests-cli"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"anyhow",
"flate2",
@@ -4559,11 +4584,11 @@ dependencies = [
[[package]]
name = "wasmer-integration-tests-ios"
version = "3.0.2"
version = "3.1.0"
[[package]]
name = "wasmer-middlewares"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"wasmer",
"wasmer-types",
@@ -4572,7 +4597,7 @@ dependencies = [
[[package]]
name = "wasmer-object"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"object 0.28.4",
"thiserror",
@@ -4581,17 +4606,20 @@ dependencies = [
[[package]]
name = "wasmer-registry"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"anyhow",
"dirs",
"filetime",
"flate2",
"fs_extra",
"futures-util",
"graphql_client",
"hex",
"log",
"lzma-rs",
"rand 0.8.5",
"regex",
"reqwest",
"semver 1.0.14",
"serde",
@@ -4599,6 +4627,7 @@ dependencies = [
"tar",
"tempdir",
"thiserror",
"tldextract",
"tokio",
"toml",
"url",
@@ -4609,7 +4638,7 @@ dependencies = [
[[package]]
name = "wasmer-types"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"enum-iterator",
"enumset",
@@ -4625,7 +4654,7 @@ dependencies = [
[[package]]
name = "wasmer-vbus"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"libc",
"slab",
@@ -4639,7 +4668,7 @@ dependencies = [
[[package]]
name = "wasmer-vfs"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"anyhow",
"async-trait",
@@ -4662,7 +4691,7 @@ dependencies = [
[[package]]
name = "wasmer-vm"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"backtrace",
"cc",
@@ -4687,7 +4716,7 @@ dependencies = [
[[package]]
name = "wasmer-vnet"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"async-trait",
"bytes",
@@ -4697,7 +4726,7 @@ dependencies = [
[[package]]
name = "wasmer-wasi"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"anyhow",
"async-trait",
@@ -4756,7 +4785,7 @@ dependencies = [
[[package]]
name = "wasmer-wasi-experimental-io-devices"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"minifb",
"nix 0.25.0",
@@ -4769,7 +4798,7 @@ dependencies = [
[[package]]
name = "wasmer-wasi-local-networking"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"async-trait",
"bytes",
@@ -4781,7 +4810,7 @@ dependencies = [
[[package]]
name = "wasmer-wasi-types"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"anyhow",
"bitflags",
@@ -4803,7 +4832,7 @@ dependencies = [
[[package]]
name = "wasmer-wast"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"anyhow",
"serde",
@@ -4818,7 +4847,7 @@ dependencies = [
[[package]]
name = "wasmer-workspace"
version = "3.0.2"
version = "3.1.0"
dependencies = [
"anyhow",
"build-deps",

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-workspace"
version = "3.0.2"
version = "3.1.0"
description = "Wasmer workspace"
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
repository = "https://github.com/wasmerio/wasmer"
@@ -10,18 +10,18 @@ publish = false
autoexamples = false
[dependencies]
wasmer = { version = "=3.0.2", path = "lib/api", default-features = false }
wasmer-compiler = { version = "=3.0.2", path = "lib/compiler", features = ["compiler"] }
wasmer-compiler-cranelift = { version = "=3.0.2", path = "lib/compiler-cranelift", optional = true }
wasmer-compiler-singlepass = { version = "=3.0.2", path = "lib/compiler-singlepass", optional = true }
wasmer-compiler-llvm = { version = "=3.0.2", path = "lib/compiler-llvm", optional = true }
wasmer-emscripten = { version = "=3.0.2", path = "lib/emscripten", optional = true }
wasmer-wasi = { version = "=3.0.2", path = "lib/wasi", optional = true }
wasmer-wast = { version = "=3.0.2", path = "tests/lib/wast", optional = true }
wasi-test-generator = { version = "=3.0.2", path = "tests/wasi-wast", optional = true }
wasmer-cache = { version = "=3.0.2", path = "lib/cache", optional = true }
wasmer-types = { version = "=3.0.2", path = "lib/types" }
wasmer-middlewares = { version = "=3.0.2", path = "lib/middlewares", optional = true }
wasmer = { version = "=3.1.0", path = "lib/api", default-features = false }
wasmer-compiler = { version = "=3.1.0", path = "lib/compiler", features = ["compiler"] }
wasmer-compiler-cranelift = { version = "=3.1.0", path = "lib/compiler-cranelift", optional = true }
wasmer-compiler-singlepass = { version = "=3.1.0", path = "lib/compiler-singlepass", optional = true }
wasmer-compiler-llvm = { version = "=3.1.0", path = "lib/compiler-llvm", optional = true }
wasmer-emscripten = { version = "=3.1.0", path = "lib/emscripten", optional = true }
wasmer-wasi = { version = "=3.1.0", path = "lib/wasi", optional = true }
wasmer-wast = { version = "=3.1.0", path = "tests/lib/wast", optional = true }
wasi-test-generator = { version = "=3.1.0", path = "tests/wasi-wast", optional = true }
wasmer-cache = { version = "=3.1.0", path = "lib/cache", optional = true }
wasmer-types = { version = "=3.1.0", path = "lib/types" }
wasmer-middlewares = { version = "=3.1.0", path = "lib/middlewares", optional = true }
cfg-if = "1.0"
[workspace]
@@ -70,7 +70,7 @@ glob = "0.3"
rustc_version = "0.4"
[dev-dependencies]
wasmer = { version = "=3.0.2", path = "lib/api", default-features = false, features = ["cranelift"] }
wasmer = { version = "=3.1.0", path = "lib/api", default-features = false, features = ["cranelift"] }
anyhow = "1.0"
criterion = "0.3"
lazy_static = "1.4"

View File

@@ -550,7 +550,7 @@ test-examples:
$(CARGO_BINARY) test $(CARGO_TARGET) --release $(compiler_features) --features wasi --examples
test-integration-cli:
$(CARGO_BINARY) test $(CARGO_TARGET) --features webc_runner --no-fail-fast -p wasmer-integration-tests-cli -- --nocapture
$(CARGO_BINARY) test $(CARGO_TARGET) --features webc_runner --no-fail-fast -p wasmer-integration-tests-cli -- --nocapture --test-threads=1
test-integration-ios:
$(CARGO_BINARY) test $(CARGO_TARGET) --features webc_runner -p wasmer-integration-tests-ios

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer"
version = "3.0.2"
version = "3.1.0"
description = "High-performance WebAssembly runtime"
categories = ["wasm"]
keywords = ["wasm", "webassembly", "runtime", "vm"]
@@ -35,15 +35,15 @@ tracing = { version = "0.1", optional = true }
# Dependencies and Development Dependencies for `sys`.
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
# - Mandatory dependencies for `sys`.
wasmer-vm = { path = "../vm", version = "=3.0.2" }
wasmer-compiler = { path = "../compiler", version = "=3.0.2" }
wasmer-derive = { path = "../derive", version = "=3.0.2" }
wasmer-types = { path = "../types", version = "=3.0.2" }
wasmer-vm = { path = "../vm", version = "=3.1.0" }
wasmer-compiler = { path = "../compiler", version = "=3.1.0" }
wasmer-derive = { path = "../derive", version = "=3.1.0" }
wasmer-types = { path = "../types", version = "=3.1.0" }
target-lexicon = { version = "0.12.2", default-features = false }
# - Optional dependencies for `sys`.
wasmer-compiler-singlepass = { path = "../compiler-singlepass", version = "=3.0.2", optional = true }
wasmer-compiler-cranelift = { path = "../compiler-cranelift", version = "=3.0.2", optional = true }
wasmer-compiler-llvm = { path = "../compiler-llvm", version = "=3.0.2", optional = true }
wasmer-compiler-singlepass = { path = "../compiler-singlepass", version = "=3.1.0", optional = true }
wasmer-compiler-cranelift = { path = "../compiler-cranelift", version = "=3.1.0", optional = true }
wasmer-compiler-llvm = { path = "../compiler-llvm", version = "=3.1.0", optional = true }
wasm-bindgen = { version = "0.2.74", optional = true }
js-sys = { version = "0.3.51", optional = true }
@@ -56,16 +56,17 @@ winapi = "0.3"
wat = "1.0"
tempfile = "3.1"
anyhow = "1.0"
macro-wasmer-universal-test = { version = "3.0.2", path = "./macro-wasmer-universal-test" }
macro-wasmer-universal-test = { version = "3.1.0", path = "./macro-wasmer-universal-test" }
# Dependencies and Develoment Dependencies for `js`.
[target.'cfg(target_arch = "wasm32")'.dependencies]
# - Mandatory dependencies for `js`.
wasmer-types = { path = "../types", version = "=3.0.2", default-features = false, features = ["std"] }
wasmer-types = { path = "../types", version = "=3.1.0", default-features = false, features = ["std"] }
wasm-bindgen = "0.2.74"
wasm-bindgen-downcast = { version = "0.1.1" }
js-sys = "0.3.51"
#web-sys = { version = "0.3.51", features = [ "console" ] }
wasmer-derive = { path = "../derive", version = "=3.0.2" }
wasmer-derive = { path = "../derive", version = "=3.1.0" }
# - Optional dependencies for `js`.
wasmparser = { version = "0.83", default-features = false, optional = true }
hashbrown = { version = "0.11", optional = true }
@@ -77,7 +78,7 @@ serde = { version = "1.0", features = ["derive"] }
wat = "1.0"
anyhow = "1.0"
wasm-bindgen-test = "0.3.0"
macro-wasmer-universal-test = { version = "3.0.2", path = "./macro-wasmer-universal-test" }
macro-wasmer-universal-test = { version = "3.1.0", path = "./macro-wasmer-universal-test" }
# Specific to `js`.
#

View File

@@ -1,6 +1,6 @@
[package]
name = "macro-wasmer-universal-test"
version = "3.0.2"
version = "3.1.0"
edition = "2021"
license = "MIT"
description = "Universal test macro for wasmer-test"

View File

@@ -5,6 +5,7 @@ use std::sync::Arc;
use wasm_bindgen::convert::FromWasmAbi;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsValue;
use wasm_bindgen_downcast::DowncastJS;
pub trait CoreError: fmt::Debug + fmt::Display {
fn source(&self) -> Option<&(dyn CoreError + 'static)> {
@@ -97,7 +98,7 @@ impl dyn CoreError {
/// A struct representing an aborted instruction execution, with a message
/// indicating the cause.
#[wasm_bindgen]
#[derive(Clone)]
#[derive(Clone, DowncastJS)]
pub struct WasmerRuntimeError {
inner: Arc<RuntimeErrorSource>,
}
@@ -285,7 +286,7 @@ impl From<JsValue> for RuntimeError {
// We try to downcast the error and see if it's
// an instance of RuntimeError instead, so we don't need
// to re-wrap it.
generic_of_jsval(original, "WasmerRuntimeError").unwrap_or_else(|js| RuntimeError {
WasmerRuntimeError::downcast_js(original).unwrap_or_else(|js| RuntimeError {
inner: Arc::new(RuntimeErrorSource::Js(js)),
})
}

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-c-api"
version = "3.0.2"
version = "3.1.0"
description = "Wasmer C API library"
categories = ["wasm", "api-bindings"]
keywords = ["wasm", "webassembly", "runtime"]
@@ -22,16 +22,16 @@ crate-type = ["staticlib", "cdylib"] #"cdylib", "rlib", "staticlib"]
[dependencies]
# We rename `wasmer` to `wasmer-api` to avoid the conflict with this
# library name (see `[lib]`).
wasmer-api = { version = "=3.0.2", path = "../api", default-features = false, features = ["sys"], package = "wasmer" }
wasmer-compiler-cranelift = { version = "=3.0.2", path = "../compiler-cranelift", optional = true }
wasmer-compiler-singlepass = { version = "=3.0.2", path = "../compiler-singlepass", optional = true }
wasmer-compiler-llvm = { version = "=3.0.2", path = "../compiler-llvm", optional = true }
wasmer-emscripten = { version = "=3.0.2", path = "../emscripten", optional = true }
wasmer-compiler = { version = "=3.0.2", path = "../compiler" }
wasmer-middlewares = { version = "=3.0.2", path = "../middlewares", optional = true }
wasmer-wasi = { version = "=3.0.2", path = "../wasi", default-features = false, features = ["host-fs", "sys"], optional = true }
wasmer-types = { version = "=3.0.2", path = "../types" }
wasmer-vfs = { version = "=3.0.2", path = "../vfs", optional = true, default-features = false, features = ["static-fs"] }
wasmer-api = { version = "=3.1.0", path = "../api", default-features = false, features = ["sys"], package = "wasmer" }
wasmer-compiler-cranelift = { version = "=3.1.0", path = "../compiler-cranelift", optional = true }
wasmer-compiler-singlepass = { version = "=3.1.0", path = "../compiler-singlepass", optional = true }
wasmer-compiler-llvm = { version = "=3.1.0", path = "../compiler-llvm", optional = true }
wasmer-emscripten = { version = "=3.1.0", path = "../emscripten", optional = true }
wasmer-compiler = { version = "=3.1.0", path = "../compiler" }
wasmer-middlewares = { version = "=3.1.0", path = "../middlewares", optional = true }
wasmer-wasi = { version = "=3.1.0", path = "../wasi", default-features = false, features = ["host-fs", "sys"], optional = true }
wasmer-types = { version = "=3.1.0", path = "../types" }
wasmer-vfs = { version = "=3.1.0", path = "../vfs", optional = true, default-features = false, features = ["static-fs"] }
webc = { version = "3.0.1", optional = true }
enumset = "1.0.2"
cfg-if = "1.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-capi-examples-runner"
version = "3.0.2"
version = "3.1.0"
edition = "2021"
license = "MIT"
description = "wasmer-capi-examples-runner"

View File

@@ -11,6 +11,7 @@ pub struct wasm_importtype_t {
}
wasm_declare_boxed_vec!(importtype);
wasm_impl_copy!(importtype);
#[no_mangle]
pub extern "C" fn wasm_importtype_new(

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-c-api-test-runner"
version = "3.0.2"
version = "3.1.0"
edition = "2021"
license = "MIT"
description = "wasmer-c-api-test-runner"

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-cache"
version = "3.0.2"
version = "3.1.0"
description = "Cache system for Wasmer WebAssembly runtime"
categories = ["wasm", "caching"]
keywords = ["wasm", "webassembly", "cache"]
@@ -11,7 +11,7 @@ readme = "README.md"
edition = "2018"
[dependencies]
wasmer = { path = "../api", version = "=3.0.2", default-features = false, features = ["sys"] }
wasmer = { path = "../api", version = "=3.1.0", default-features = false, features = ["sys"] }
hex = "0.4"
thiserror = "1"
blake3 = "1.0"
@@ -20,7 +20,7 @@ blake3 = "1.0"
criterion = "0.3"
tempfile = "3"
rand = "0.8.3"
wasmer-compiler-singlepass = { path = "../compiler-singlepass", version = "=3.0.2" }
wasmer-compiler-singlepass = { path = "../compiler-singlepass", version = "=3.1.0" }
[features]
default = ["wasmer/js-serializable-module", "wasmer/compiler", "filesystem"]

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-compiler-cli"
version = "3.0.2"
version = "3.1.0"
description = "Wasmer Compiler CLI"
categories = ["wasm", "command-line-interface"]
keywords = ["wasm", "webassembly", "cli"]
@@ -18,8 +18,8 @@ path = "src/bin/wasmer_compiler.rs"
doc = false
[dependencies]
wasmer-compiler = { version = "=3.0.2", path = "../compiler", features = ["compiler"] }
wasmer-types = { version = "=3.0.2", path = "../types" }
wasmer-compiler = { version = "=3.1.0", path = "../compiler", features = ["compiler"] }
wasmer-types = { version = "=3.1.0", path = "../types" }
atty = "0.2"
colored = "2.0"
anyhow = "1.0"
@@ -36,12 +36,12 @@ target-lexicon = { version = "0.12", features = ["std"] }
tempfile = "3"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
wasmer-compiler-singlepass = { version = "=3.0.2", path = "../compiler-singlepass", optional = true }
wasmer-compiler-cranelift = { version = "=3.0.2", path = "../compiler-cranelift", optional = true }
wasmer-compiler-singlepass = { version = "=3.1.0", path = "../compiler-singlepass", optional = true }
wasmer-compiler-cranelift = { version = "=3.1.0", path = "../compiler-cranelift", optional = true }
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasmer-compiler-singlepass = { version = "=3.0.2", path = "../compiler-singlepass", optional = true, default-features = false, features = ["wasm"] }
wasmer-compiler-cranelift = { version = "=3.0.2", path = "../compiler-cranelift", optional = true, default-features = false, features = ["wasm"] }
wasmer-compiler-singlepass = { version = "=3.1.0", path = "../compiler-singlepass", optional = true, default-features = false, features = ["wasm"] }
wasmer-compiler-cranelift = { version = "=3.1.0", path = "../compiler-cranelift", optional = true, default-features = false, features = ["wasm"] }
[target.'cfg(target_os = "linux")'.dependencies]
unix_mode = "0.1.3"

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-cli"
version = "3.0.2"
version = "3.1.0"
description = "Wasmer CLI"
categories = ["wasm", "command-line-interface"]
keywords = ["wasm", "webassembly", "cli"]
@@ -25,21 +25,21 @@ doc = false
required-features = ["headless"]
[dependencies]
wasmer = { version = "=3.0.2", path = "../api", default-features = false }
wasmer-compiler = { version = "=3.0.2", path = "../compiler", features = ["compiler", ] }
wasmer-compiler-cranelift = { version = "=3.0.2", path = "../compiler-cranelift", optional = true }
wasmer-compiler-singlepass = { version = "=3.0.2", path = "../compiler-singlepass", optional = true }
wasmer-compiler-llvm = { version = "=3.0.2", path = "../compiler-llvm", optional = true }
wasmer-emscripten = { version = "=3.0.2", path = "../emscripten", optional = true }
wasmer-vm = { version = "=3.0.2", path = "../vm", features = ["tracing"] }
wasmer-wasi = { version = "=3.0.2", path = "../wasi", optional = true, features = ["host-vnet"] }
wasmer-wasi-experimental-io-devices = { version = "=3.0.2", path = "../wasi-experimental-io-devices", optional = true, features = ["link_external_libs"] }
wasmer-wast = { version = "=3.0.2", path = "../../tests/lib/wast", optional = true }
wasmer-cache = { version = "=3.0.2", path = "../cache", optional = true }
wasmer-types = { version = "=3.0.2", path = "../types" }
wasmer-registry = { version = "=3.0.2", path = "../registry" }
wasmer-object = { version = "=3.0.2", path = "../object", optional = true }
wasmer-vfs = { version = "=3.0.2", path = "../vfs", default-features = false, features = ["host-fs"] }
wasmer = { version = "=3.1.0", path = "../api", default-features = false }
wasmer-compiler = { version = "=3.1.0", path = "../compiler", features = ["compiler", ] }
wasmer-compiler-cranelift = { version = "=3.1.0", path = "../compiler-cranelift", optional = true }
wasmer-compiler-singlepass = { version = "=3.1.0", path = "../compiler-singlepass", optional = true }
wasmer-compiler-llvm = { version = "=3.1.0", path = "../compiler-llvm", optional = true }
wasmer-emscripten = { version = "=3.1.0", path = "../emscripten", optional = true }
wasmer-vm = { version = "=3.1.0", path = "../vm" }
wasmer-wasi = { version = "=3.1.0", path = "../wasi", optional = true }
wasmer-wasi-experimental-io-devices = { version = "=3.1.0", path = "../wasi-experimental-io-devices", optional = true, features = ["link_external_libs"] }
wasmer-wast = { version = "=3.1.0", path = "../../tests/lib/wast", optional = true }
wasmer-cache = { version = "=3.1.0", path = "../cache", optional = true }
wasmer-types = { version = "=3.1.0", path = "../types" }
wasmer-registry = { version = "=3.1.0", path = "../registry" }
wasmer-object = { version = "=3.1.0", path = "../object", optional = true }
wasmer-vfs = { version = "=3.1.0", path = "../vfs", default-features = false, features = ["host-fs"] }
atty = "0.2"
colored = "2.0"
anyhow = "1.0"
@@ -55,11 +55,11 @@ fern = { version = "0.6", features = ["colored"], optional = true }
log = { version = "0.4", optional = true }
tempfile = "3"
tempdir = "0.3.7"
http_req = { version="^0.8", default-features = false, features = ["rust-tls"], optional = true }
reqwest = { version = "^0.11", default-features = false, features = ["rustls-tls", "json", "multipart"], optional = true }
serde = { version = "1.0.147", features = ["derive"], optional = true }
dirs = { version = "4.0", optional = true }
serde_json = { version = "1.0", optional = true }
http_req = { version="^0.8", default-features = false, features = ["rust-tls"] }
reqwest = { version = "^0.11", default-features = false, features = ["rustls-tls", "json", "multipart"] }
serde = { version = "1.0.147", features = ["derive"] }
dirs = { version = "4.0" }
serde_json = { version = "1.0" }
target-lexicon = { version = "0.12", features = ["std"] }
prettytable-rs = "0.9.0"
wapm-toml = "0.2.0"
@@ -73,6 +73,7 @@ webc = { version = "3.0.1", optional = true }
isatty = "0.1.9"
dialoguer = "0.10.2"
tldextract = "0.6.0"
hex = "0.4.3"
[build-dependencies]
chrono = { version = "^0.4", default-features = false, features = [ "std", "clock" ] }
@@ -86,7 +87,6 @@ unix_mode = "0.1.3"
default = [
"wat",
"wast",
"http",
"cache",
"wasi",
"emscripten",
@@ -160,14 +160,6 @@ enable-serde = [
"wasmer-wasi/enable-serde",
]
http = [
"http_req",
"reqwest",
"dirs",
"serde_json",
"serde",
]
[target.'cfg(target_os = "windows")'.dependencies]
colored = "2.0.0"

View File

@@ -15,7 +15,6 @@ use crate::commands::{
};
use crate::error::PrettyError;
use clap::{CommandFactory, ErrorKind, Parser};
use std::{fmt, str::FromStr};
#[derive(Parser, Debug)]
#[cfg_attr(
@@ -243,218 +242,9 @@ fn wasmer_main_inner() -> Result<(), anyhow::Error> {
}
};
// Check if the file is a package name
if let WasmerCLIOptions::Run(r) = &options {
#[cfg(not(feature = "debug"))]
let debug = false;
#[cfg(feature = "debug")]
let debug = r.options.debug;
return crate::commands::try_run_package_or_file(&args, r, debug);
}
options.execute()
}
#[derive(Debug, Clone, PartialEq, Default)]
pub(crate) struct SplitVersion {
pub(crate) original: String,
pub(crate) registry: Option<String>,
pub(crate) package: String,
pub(crate) version: Option<String>,
pub(crate) command: Option<String>,
}
impl fmt::Display for SplitVersion {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let version = self.version.as_deref().unwrap_or("latest");
let command = self
.command
.as_ref()
.map(|s| format!(":{s}"))
.unwrap_or_default();
write!(f, "{}@{version}{command}", self.package)
}
}
#[test]
fn test_split_version() {
assert_eq!(
SplitVersion::parse("registry.wapm.io/graphql/python/python").unwrap(),
SplitVersion {
original: "registry.wapm.io/graphql/python/python".to_string(),
registry: Some("https://registry.wapm.io/graphql".to_string()),
package: "python/python".to_string(),
version: None,
command: None,
}
);
assert_eq!(
SplitVersion::parse("registry.wapm.io/python/python").unwrap(),
SplitVersion {
original: "registry.wapm.io/python/python".to_string(),
registry: Some("https://registry.wapm.io/graphql".to_string()),
package: "python/python".to_string(),
version: None,
command: None,
}
);
assert_eq!(
SplitVersion::parse("namespace/name@version:command").unwrap(),
SplitVersion {
original: "namespace/name@version:command".to_string(),
registry: None,
package: "namespace/name".to_string(),
version: Some("version".to_string()),
command: Some("command".to_string()),
}
);
assert_eq!(
SplitVersion::parse("namespace/name@version").unwrap(),
SplitVersion {
original: "namespace/name@version".to_string(),
registry: None,
package: "namespace/name".to_string(),
version: Some("version".to_string()),
command: None,
}
);
assert_eq!(
SplitVersion::parse("namespace/name").unwrap(),
SplitVersion {
original: "namespace/name".to_string(),
registry: None,
package: "namespace/name".to_string(),
version: None,
command: None,
}
);
assert_eq!(
SplitVersion::parse("registry.wapm.io/namespace/name").unwrap(),
SplitVersion {
original: "registry.wapm.io/namespace/name".to_string(),
registry: Some("https://registry.wapm.io/graphql".to_string()),
package: "namespace/name".to_string(),
version: None,
command: None,
}
);
assert_eq!(
format!("{}", SplitVersion::parse("namespace").unwrap_err()),
"Invalid package version: \"namespace\"".to_string(),
);
}
impl SplitVersion {
pub fn parse(s: &str) -> Result<SplitVersion, anyhow::Error> {
s.parse()
}
}
impl FromStr for SplitVersion {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let command = WasmerCLIOptions::command();
let mut prohibited_package_names = command.get_subcommands().map(|s| s.get_name());
let re1 = regex::Regex::new(r#"(.*)/(.*)@(.*):(.*)"#).unwrap();
let re2 = regex::Regex::new(r#"(.*)/(.*)@(.*)"#).unwrap();
let re3 = regex::Regex::new(r#"(.*)/(.*)"#).unwrap();
let re4 = regex::Regex::new(r#"(.*)/(.*):(.*)"#).unwrap();
let mut no_version = false;
let captures = if re1.is_match(s) {
re1.captures(s)
.map(|c| {
c.iter()
.flatten()
.map(|m| m.as_str().to_owned())
.collect::<Vec<_>>()
})
.unwrap_or_default()
} else if re2.is_match(s) {
re2.captures(s)
.map(|c| {
c.iter()
.flatten()
.map(|m| m.as_str().to_owned())
.collect::<Vec<_>>()
})
.unwrap_or_default()
} else if re4.is_match(s) {
no_version = true;
re4.captures(s)
.map(|c| {
c.iter()
.flatten()
.map(|m| m.as_str().to_owned())
.collect::<Vec<_>>()
})
.unwrap_or_default()
} else if re3.is_match(s) {
re3.captures(s)
.map(|c| {
c.iter()
.flatten()
.map(|m| m.as_str().to_owned())
.collect::<Vec<_>>()
})
.unwrap_or_default()
} else {
return Err(anyhow::anyhow!("Invalid package version: {s:?}"));
};
let mut namespace = match captures.get(1).cloned() {
Some(s) => s,
None => {
return Err(anyhow::anyhow!(
"Invalid package version: {s:?}: no namespace"
))
}
};
let name = match captures.get(2).cloned() {
Some(s) => s,
None => return Err(anyhow::anyhow!("Invalid package version: {s:?}: no name")),
};
let mut registry = None;
if namespace.contains('/') {
let (r, n) = namespace.rsplit_once('/').unwrap();
let mut real_registry = r.to_string();
if !real_registry.ends_with("graphql") {
real_registry = format!("{real_registry}/graphql");
}
if !real_registry.contains("://") {
real_registry = format!("https://{real_registry}");
}
registry = Some(real_registry);
namespace = n.to_string();
}
let sv = SplitVersion {
original: s.to_string(),
registry,
package: format!("{namespace}/{name}"),
version: if no_version {
None
} else {
captures.get(3).cloned()
},
command: captures.get(if no_version { 3 } else { 4 }).cloned(),
};
let svp = sv.package.clone();
anyhow::ensure!(
!prohibited_package_names.any(|s| s == sv.package.trim()),
"Invalid package name {svp:?}"
);
Ok(sv)
}
}
fn print_help(verbose: bool) -> Result<(), anyhow::Error> {
let mut cmd = WasmerCLIOptions::command();
if verbose {

View File

@@ -4,8 +4,6 @@ use anyhow::{Context, Error};
use clap::Parser;
use wasmer_registry::{Bindings, PartialWapmConfig, ProgrammingLanguage};
use crate::cli::SplitVersion;
/// Add a WAPM package's bindings to your application.
#[derive(Debug, Parser)]
pub struct Add {
@@ -26,7 +24,7 @@ pub struct Add {
pip: bool,
/// The packages to add (e.g. "wasmer/wasmer-pack@0.5.0" or "python/python")
#[clap(parse(try_from_str))]
packages: Vec<SplitVersion>,
packages: Vec<wasmer_registry::Package>,
}
impl Add {
@@ -103,11 +101,11 @@ impl Add {
fn lookup_bindings_for_package(
registry: &str,
pkg: &SplitVersion,
pkg: &wasmer_registry::Package,
language: &ProgrammingLanguage,
) -> Result<Bindings, Error> {
let all_bindings =
wasmer_registry::list_bindings(registry, &pkg.package, pkg.version.as_deref())?;
wasmer_registry::list_bindings(registry, &pkg.package(), pkg.version.as_deref())?;
match all_bindings.iter().find(|b| b.language == *language) {
Some(b) => {

View File

@@ -402,52 +402,34 @@ impl CreateExe {
let library = if let Some(v) = cross_subc.library_path.clone() {
v.canonicalize().unwrap_or(v)
} else {
{
let libwasmer_path = "lib/libwasmer.a";
let tarball_dir;
let filename = if let Some(local_tarball) = cross_subc.tarball.as_ref() {
let target_file_path = local_tarball
.parent()
.and_then(|parent| Some(parent.join(local_tarball.file_stem()?)))
.unwrap_or_else(|| local_tarball.clone());
let target_file_path = target_file_path
.parent()
.and_then(|parent| Some(parent.join(target_file_path.file_stem()?)))
.unwrap_or_else(|| target_file_path.clone());
let _ = std::fs::create_dir_all(&target_file_path);
let files = untar(local_tarball.clone(), target_file_path.clone())?;
tarball_dir = target_file_path.canonicalize().unwrap_or(target_file_path);
files.iter().find(|f| f.contains(libwasmer_path)).cloned().ok_or_else(|| {
anyhow!("Could not find libwasmer for {} target in the provided tarball path (files = {files:#?}, libwasmer_path = {libwasmer_path:?})", target)})?
let (filename, tarball_dir) =
if let Some(local_tarball) = cross_subc.tarball.as_ref() {
Self::find_filename(local_tarball, &target)
} else {
// check if the tarball for the target already exists locally
let local_tarball = std::fs::read_dir(get_libwasmer_cache_path()?)?
.filter_map(|e| e.ok())
.filter_map(|e| {
let path = format!("{}", e.path().display());
if path.ends_with(".tar.gz") {
Some(e.path())
} else {
None
}
})
.filter_map(|p| Self::filter_tarballs(&p, &target))
.next();
if let Some(local_tarball) = local_tarball.as_ref() {
Self::find_filename(local_tarball, &target)
} else {
#[cfg(feature = "http")]
{
let release = http_fetch::get_latest_release()?;
let tarball = http_fetch::download_release(release, target.clone())?;
let target_file_path = tarball
.parent()
.and_then(|parent| Some(parent.join(tarball.file_stem()?)))
.unwrap_or_else(|| tarball.clone());
let target_file_path = target_file_path
.parent()
.and_then(|parent| Some(parent.join(target_file_path.file_stem()?)))
.unwrap_or_else(|| target_file_path.clone());
tarball_dir = target_file_path
.canonicalize()
.unwrap_or_else(|_| target_file_path.clone());
let files = untar(tarball, target_file_path)?;
files.into_iter().find(|f| f.contains(libwasmer_path)).ok_or_else(|| {
anyhow!("Could not find libwasmer for {} target in the fetched release from Github: you can download it manually and specify its path with the --cross-compilation-library-path LIBRARY_PATH flag.", target)})?
Self::find_filename(&tarball, &target)
}
#[cfg(not(feature = "http"))]
return Err(anyhow!("This wasmer binary isn't compiled with an HTTP request library (feature flag `http`). To cross-compile, specify the path of the non-native libwasmer or release tarball with the --library-path LIBRARY_PATH or --tarball TARBALL_PATH flag."));
};
}?;
tarball_dir.join(&filename)
}
};
let ccs = CrossCompileSetup {
target,
@@ -460,6 +442,72 @@ impl CreateExe {
}
}
fn find_filename(
local_tarball: &Path,
target: &Triple,
) -> Result<(String, PathBuf), anyhow::Error> {
let target_file_path = local_tarball
.parent()
.and_then(|parent| Some(parent.join(local_tarball.file_stem()?)))
.unwrap_or_else(|| local_tarball.to_path_buf());
let target_file_path = target_file_path
.parent()
.and_then(|parent| Some(parent.join(target_file_path.file_stem()?)))
.unwrap_or_else(|| target_file_path.clone());
std::fs::create_dir_all(&target_file_path)
.map_err(|e| anyhow::anyhow!("{e}"))
.context(anyhow::anyhow!("{}", target_file_path.display()))?;
let files = untar(local_tarball.to_path_buf(), target_file_path.clone())?;
let tarball_dir = target_file_path.canonicalize().unwrap_or(target_file_path);
let file = files
.iter()
.find(|f| f.ends_with("libwasmer.a")).cloned()
.ok_or_else(|| {
anyhow!("Could not find libwasmer.a for {} target in the provided tarball path (files = {files:#?})", target)
})?;
Ok((file, tarball_dir))
}
fn filter_tarballs(p: &Path, target: &Triple) -> Option<PathBuf> {
if let Architecture::Aarch64(_) = target.architecture {
if !p.file_name()?.to_str()?.contains("aarch64") {
return None;
}
}
if let Architecture::X86_64 = target.architecture {
if !p.file_name()?.to_str()?.contains("x86_64") {
return None;
}
}
if let OperatingSystem::Windows = target.operating_system {
if !p.file_name()?.to_str()?.contains("windows") {
return None;
}
}
if let OperatingSystem::Darwin = target.operating_system {
if !(p.file_name()?.to_str()?.contains("apple")
|| p.file_name()?.to_str()?.contains("darwin"))
{
return None;
}
}
if let OperatingSystem::Linux = target.operating_system {
if !p.file_name()?.to_str()?.contains("linux") {
return None;
}
}
Some(p.to_path_buf())
}
fn compile_c(
&self,
wasm_object_path: PathBuf,
@@ -573,9 +621,6 @@ impl CreateExe {
}
cmd.arg("-lunwind");
cmd.arg("-OReleaseSafe");
cmd.arg("-fstrip");
cmd.arg("-dead_strip");
cmd.arg("-dead_strip_dylibs");
cmd.arg("-fno-compiler-rt");
cmd.arg(&format!("-femit-bin={}", output_path.display()));
@@ -1329,7 +1374,6 @@ impl LinkCode {
}
}
#[cfg(feature = "http")]
mod http_fetch {
use anyhow::{anyhow, Context, Result};
use http_req::{request::Request, response::StatusCode, uri::Uri};
@@ -1379,7 +1423,7 @@ mod http_fetch {
}
Err(anyhow!(
"Could not get expected Github API response.\n\nReason: response format is not recognized:\n{:#?}", ""
"Could not get expected Github API response.\n\nReason: response format is not recognized:\n{response:#?}",
))
}

View File

@@ -9,10 +9,10 @@ impl List {
pub fn execute(&self) -> Result<(), anyhow::Error> {
use prettytable::{format, row, Table};
let rows = wasmer_registry::get_all_local_packages(None)
let rows = wasmer_registry::get_all_local_packages()
.into_iter()
.filter_map(|pkg| {
let package_root_path = pkg.get_path().ok()?;
let package_root_path = pkg.path;
let (manifest, _) =
wasmer_registry::get_executable_file_from_path(&package_root_path, None)
.ok()?;

View File

@@ -1,7 +1,7 @@
use crate::cli::SplitVersion;
use crate::common::get_cache_dir;
#[cfg(feature = "debug")]
use crate::logging;
use crate::package_source::PackageSource;
use crate::store::{CompilerType, StoreOptions};
use crate::suggestions::suggest_function_exports;
use crate::warning;
@@ -11,12 +11,10 @@ use std::collections::HashMap;
use std::ops::Deref;
use std::path::PathBuf;
use std::str::FromStr;
use url::Url;
use wasmer::FunctionEnv;
use wasmer::*;
#[cfg(feature = "cache")]
use wasmer_cache::{Cache, FileSystemCache, Hash};
use wasmer_registry::PackageDownloadInfo;
use wasmer_types::Type as ValueType;
#[cfg(feature = "webc_runner")]
use wasmer_wasi::runners::{Runner, WapmContainer};
@@ -27,6 +25,17 @@ mod wasi;
#[cfg(feature = "wasi")]
use wasi::Wasi;
/// The options for the `wasmer run` subcommand, runs either a package, URL or a file
#[derive(Debug, Parser, Clone, Default)]
pub struct Run {
/// File to run
#[clap(name = "SOURCE", parse(try_from_str))]
pub(crate) path: PackageSource,
/// Options to run the file / package / URL with
#[clap(flatten)]
pub(crate) options: RunWithoutFile,
}
/// Same as `wasmer run`, but without the required `path` argument (injected previously)
#[derive(Debug, Parser, Clone, Default)]
pub struct RunWithoutFile {
@@ -83,34 +92,42 @@ pub struct RunWithoutFile {
pub(crate) args: Vec<String>,
}
#[allow(dead_code)]
fn is_dir(e: &walkdir::DirEntry) -> bool {
let meta = match e.metadata() {
Ok(o) => o,
Err(_) => return false,
};
meta.is_dir()
/// Same as `Run`, but uses a resolved local file path.
#[derive(Debug, Clone, Default)]
pub struct RunWithPathBuf {
/// File to run
pub(crate) path: PathBuf,
/// Options for running the file
pub(crate) options: RunWithoutFile,
}
impl RunWithoutFile {
/// Given a local path, returns the `Run` command (overriding the `--path` argument).
pub fn into_run_args(
mut self,
package_root_dir: PathBuf, // <- package dir
command: Option<&str>,
_debug_output_allowed: bool,
) -> Result<Run, anyhow::Error> {
let (manifest, pathbuf) =
wasmer_registry::get_executable_file_from_path(&package_root_dir, command)?;
impl Deref for RunWithPathBuf {
type Target = RunWithoutFile;
fn deref(&self) -> &Self::Target {
&self.options
}
}
impl RunWithPathBuf {
/// Execute the run command
pub fn execute(&self) -> Result<()> {
let mut self_clone = self.clone();
if self_clone.path.is_dir() {
let (manifest, pathbuf) = wasmer_registry::get_executable_file_from_path(
&self_clone.path,
self_clone.command_name.as_deref(),
)?;
#[cfg(feature = "wasi")]
{
let default = HashMap::default();
let fs = manifest.fs.as_ref().unwrap_or(&default);
for (alias, real_dir) in fs.iter() {
let real_dir = package_root_dir.join(&real_dir);
let real_dir = self_clone.path.join(&real_dir);
if !real_dir.exists() {
if _debug_output_allowed {
#[cfg(feature = "debug")]
if self_clone.debug {
println!(
"warning: cannot map {alias:?} to {}: directory does not exist",
real_dir.display()
@@ -119,67 +136,21 @@ impl RunWithoutFile {
continue;
}
self.wasi.map_dir(alias, real_dir.clone());
self_clone.options.wasi.map_dir(alias, real_dir.clone());
}
}
Ok(Run {
path: pathbuf,
options: RunWithoutFile {
force_install: self.force_install,
#[cfg(feature = "cache")]
disable_cache: self.disable_cache,
invoke: self.invoke,
// If the RunWithoutFile was constructed via a package name,
// the correct syntax is "package:command-name" (--command-name would be
// interpreted as a CLI argument for the .wasm file)
command_name: None,
#[cfg(feature = "cache")]
cache_key: self.cache_key,
store: self.store,
#[cfg(feature = "wasi")]
wasi: self.wasi,
#[cfg(feature = "io-devices")]
enable_experimental_io_devices: self.enable_experimental_io_devices,
#[cfg(feature = "debug")]
debug: self.debug,
#[cfg(feature = "debug")]
verbose: self.verbose,
args: self.args,
},
})
}
self_clone.path = pathbuf;
}
#[derive(Debug, Parser, Clone, Default)]
/// The options for the `wasmer run` subcommand
pub struct Run {
/// File to run
#[clap(name = "FILE", parse(from_os_str))]
pub(crate) path: PathBuf,
#[clap(flatten)]
pub(crate) options: RunWithoutFile,
}
impl Deref for Run {
type Target = RunWithoutFile;
fn deref(&self) -> &Self::Target {
&self.options
}
}
impl Run {
/// Execute the run command
pub fn execute(&self) -> Result<()> {
#[cfg(feature = "debug")]
if self.debug {
logging::set_up_logging(self.verbose.unwrap_or(0)).unwrap();
logging::set_up_logging(self_clone.verbose.unwrap_or(0)).unwrap();
}
self.inner_execute().with_context(|| {
self_clone.inner_execute().with_context(|| {
format!(
"failed to run `{}`{}",
self.path.display(),
self_clone.path.display(),
if CompilerType::enabled().is_empty() {
" (no compilers enabled)"
} else {
@@ -589,6 +560,19 @@ impl Run {
.collect::<Result<Vec<_>>>()?;
Ok(func.call(ctx, &invoke_args)?)
}
}
impl Run {
/// Executes the `wasmer run` command
pub fn execute(&self) -> Result<(), anyhow::Error> {
// downloads and installs the package if necessary
let path_to_run = self.path.download_and_get_filepath()?;
RunWithPathBuf {
path: path_to_run,
options: self.options.clone(),
}
.execute()
}
/// Create Run instance for arguments/env,
/// assuming we're being run from a CFP binfmt interpreter.
@@ -602,364 +586,30 @@ impl Run {
#[cfg(target_os = "linux")]
fn from_binfmt_args_fallible() -> Result<Run> {
let argv = std::env::args_os().collect::<Vec<_>>();
let argv = std::env::args().collect::<Vec<_>>();
let (_interpreter, executable, original_executable, args) = match &argv[..] {
[a, b, c, d @ ..] => (a, b, c, d),
_ => {
bail!("Wasmer binfmt interpreter needs at least three arguments (including $0) - must be registered as binfmt interpreter with the CFP flags. (Got arguments: {:?})", argv);
}
};
// TODO: Optimally, args and env would be passed as an UTF-8 Vec.
// (Can be pulled out of std::os::unix::ffi::OsStrExt)
// But I don't want to duplicate or rewrite run.rs today.
let args = args
.iter()
.enumerate()
.map(|(i, s)| {
s.clone().into_string().map_err(|s| {
anyhow!(
"Cannot convert argument {} ({:?}) to UTF-8 string",
i + 1,
s
)
})
})
.collect::<Result<Vec<_>>>()?;
let original_executable = original_executable
.clone()
.into_string()
.map_err(|s| anyhow!("Cannot convert executable name {:?} to UTF-8 string", s))?;
let store = StoreOptions::default();
// TODO: store.compiler.features.all = true; ?
Ok(Self {
path: executable.into(),
// unwrap is safe, since parsing never fails
path: PackageSource::parse(executable).unwrap(),
options: RunWithoutFile {
args,
command_name: Some(original_executable),
args: args.to_vec(),
command_name: Some(original_executable.to_string()),
store,
wasi: Wasi::for_binfmt_interpreter()?,
..Default::default()
},
})
}
#[cfg(not(target_os = "linux"))]
fn from_binfmt_args_fallible() -> Result<Run> {
bail!("binfmt_misc is only available on linux.")
}
}
fn start_spinner(msg: String) -> Option<spinoff::Spinner> {
if !isatty::stdout_isatty() {
return None;
}
#[cfg(target_os = "windows")]
{
use colored::control;
let _ = control::set_virtual_terminal(true);
}
Some(spinoff::Spinner::new(
spinoff::Spinners::Dots,
msg,
spinoff::Color::White,
))
}
/// Before looking up a command from the registry, try to see if we have
/// the command already installed
fn try_run_local_command(
args: &[String],
sv: &SplitVersion,
debug_msgs_allowed: bool,
) -> Result<(), ExecuteLocalPackageError> {
let result = wasmer_registry::try_finding_local_command(&sv.original).ok_or_else(|| {
ExecuteLocalPackageError::BeforeExec(anyhow::anyhow!(
"could not find command {} locally",
sv.original
))
})?;
let package_dir = result
.get_path()
.map_err(|e| ExecuteLocalPackageError::BeforeExec(anyhow::anyhow!("{e}")))?;
// Try auto-installing the remote package
let args_without_package = fixup_args(args, &sv.original);
let mut run_args = RunWithoutFile::try_parse_from(args_without_package.iter())
.map_err(|e| ExecuteLocalPackageError::DuringExec(e.into()))?;
run_args.command_name = sv.command.clone();
run_args
.into_run_args(package_dir, sv.command.as_deref(), debug_msgs_allowed)
.map_err(ExecuteLocalPackageError::DuringExec)?
.execute()
.map_err(ExecuteLocalPackageError::DuringExec)
}
pub(crate) fn try_autoinstall_package(
args: &[String],
sv: &SplitVersion,
package: Option<PackageDownloadInfo>,
force_install: bool,
) -> Result<(), anyhow::Error> {
use std::io::Write;
let mut sp = start_spinner(format!("Installing package {} ...", sv.package));
let debug_msgs_allowed = sp.is_some();
let v = sv.version.as_deref();
let result = wasmer_registry::install_package(
sv.registry.as_deref(),
&sv.package,
v,
package,
force_install,
);
if let Some(sp) = sp.take() {
sp.clear();
}
let _ = std::io::stdout().flush();
let (_, package_dir) = match result {
Ok(o) => o,
Err(e) => {
return Err(anyhow::anyhow!("{e}"));
}
};
// Try auto-installing the remote package
let args_without_package = fixup_args(args, &sv.original);
let mut run_args = RunWithoutFile::try_parse_from(args_without_package.iter())?;
run_args.command_name = sv.command.clone();
run_args
.into_run_args(package_dir, sv.command.as_deref(), debug_msgs_allowed)?
.execute()
}
// We need to distinguish between errors that happen
// before vs. during execution
enum ExecuteLocalPackageError {
BeforeExec(anyhow::Error),
DuringExec(anyhow::Error),
}
fn try_execute_local_package(
args: &[String],
sv: &SplitVersion,
debug_msgs_allowed: bool,
) -> Result<(), ExecuteLocalPackageError> {
let package = wasmer_registry::get_local_package(None, &sv.package, sv.version.as_deref())
.ok_or_else(|| {
ExecuteLocalPackageError::BeforeExec(anyhow::anyhow!("no local package {sv:?} found"))
})?;
let package_dir = package
.get_path()
.map_err(|e| ExecuteLocalPackageError::BeforeExec(anyhow::anyhow!("{e}")))?;
// Try finding the local package
let args_without_package = fixup_args(args, &sv.original);
RunWithoutFile::try_parse_from(args_without_package.iter())
.map_err(|e| ExecuteLocalPackageError::DuringExec(e.into()))?
.into_run_args(package_dir, sv.command.as_deref(), debug_msgs_allowed)
.map_err(ExecuteLocalPackageError::DuringExec)?
.execute()
.map_err(|e| ExecuteLocalPackageError::DuringExec(e.context(anyhow::anyhow!("{}", sv))))
}
fn try_lookup_command(sv: &mut SplitVersion) -> Result<PackageDownloadInfo, anyhow::Error> {
use std::io::Write;
let mut sp = start_spinner(format!("Looking up command {} ...", sv.package));
for registry in wasmer_registry::get_all_available_registries().unwrap_or_default() {
let result = wasmer_registry::query_command_from_registry(&registry, &sv.package);
if let Some(s) = sp.take() {
s.clear();
}
let _ = std::io::stdout().flush();
let command = sv.package.clone();
if let Ok(o) = result {
sv.package = o.package.clone();
sv.version = Some(o.version.clone());
sv.command = Some(command);
return Ok(o);
}
}
if let Some(sp) = sp.take() {
sp.clear();
}
let _ = std::io::stdout().flush();
Err(anyhow::anyhow!("command {sv} not found"))
}
/// Removes the difference between "wasmer run {file} arg1 arg2" and "wasmer {file} arg1 arg2"
fn fixup_args(args: &[String], command: &str) -> Vec<String> {
let mut args_without_package = args.to_vec();
if args_without_package.get(1).map(|s| s.as_str()) == Some(command) {
let _ = args_without_package.remove(1);
} else if args_without_package.get(2).map(|s| s.as_str()) == Some(command) {
let _ = args_without_package.remove(1);
let _ = args_without_package.remove(1);
}
args_without_package
}
#[test]
fn test_fixup_args() {
let first_args = vec![
format!("wasmer"),
format!("run"),
format!("python/python"),
format!("--arg1"),
format!("--arg2"),
];
let second_args = vec![
format!("wasmer"), // no "run"
format!("python/python"),
format!("--arg1"),
format!("--arg2"),
];
let arg1_transformed = fixup_args(&first_args, "python/python");
let arg2_transformed = fixup_args(&second_args, "python/python");
assert_eq!(arg1_transformed, arg2_transformed);
}
pub(crate) fn try_run_package_or_file(
args: &[String],
r: &Run,
debug: bool,
) -> Result<(), anyhow::Error> {
let debug_msgs_allowed = isatty::stdout_isatty();
// Check "r.path" is a file or a package / command name
if r.path.exists() {
if r.path.is_dir() && r.path.join("wapm.toml").exists() {
let args_without_package = fixup_args(args, &format!("{}", r.path.display()));
return RunWithoutFile::try_parse_from(args_without_package.iter())?
.into_run_args(
r.path.clone(),
r.command_name.as_deref(),
debug_msgs_allowed,
)?
.execute();
}
return r.execute();
}
// c:// might be parsed as a URL on Windows
let url_string = format!("{}", r.path.display());
if let Ok(url) = url::Url::parse(&url_string) {
if url.scheme() == "http" || url.scheme() == "https" {
match try_run_url(&url, args, r, debug) {
Err(ExecuteLocalPackageError::BeforeExec(_)) => {}
Err(ExecuteLocalPackageError::DuringExec(e)) => return Err(e),
Ok(o) => return Ok(o),
}
}
}
let package = format!("{}", r.path.display());
let mut is_fake_sv = false;
let mut sv = match SplitVersion::parse(&package) {
Ok(o) => o,
Err(_) => {
let mut fake_sv = SplitVersion {
original: package.to_string(),
registry: None,
package: package.to_string(),
version: None,
command: None,
};
is_fake_sv = true;
match try_run_local_command(args, &fake_sv, debug) {
Ok(()) => return Ok(()),
Err(ExecuteLocalPackageError::DuringExec(e)) => return Err(e),
_ => {}
}
match try_lookup_command(&mut fake_sv) {
Ok(o) => SplitVersion {
original: package.to_string(),
registry: None,
package: o.package,
version: Some(o.version),
command: r.command_name.clone(),
},
Err(e) => {
return Err(
anyhow::anyhow!("No package for command {package:?} found, file {package:?} not found either")
.context(e)
.context(anyhow::anyhow!("{}", r.path.display()))
);
}
}
}
};
if sv.command.is_none() {
sv.command = r.command_name.clone();
}
if sv.command.is_none() && is_fake_sv {
sv.command = Some(package);
}
let mut package_download_info = None;
if !sv.package.contains('/') {
if let Ok(o) = try_lookup_command(&mut sv) {
package_download_info = Some(o);
}
}
match try_execute_local_package(args, &sv, debug_msgs_allowed) {
Ok(o) => return Ok(o),
Err(ExecuteLocalPackageError::DuringExec(e)) => return Err(e),
_ => {}
}
if debug && isatty::stdout_isatty() {
eprintln!("finding local package {} failed", sv);
}
// else: local package not found - try to download and install package
try_autoinstall_package(args, &sv, package_download_info, r.force_install)
}
fn try_run_url(
url: &Url,
_args: &[String],
r: &Run,
_debug: bool,
) -> Result<(), ExecuteLocalPackageError> {
let checksum = wasmer_registry::get_remote_webc_checksum(url).map_err(|e| {
ExecuteLocalPackageError::BeforeExec(anyhow::anyhow!("error fetching {url}: {e}"))
})?;
let packages = wasmer_registry::get_all_installed_webc_packages();
if !packages.iter().any(|p| p.checksum == checksum) {
let sp = start_spinner(format!("Installing {}", url));
let result = wasmer_registry::install_webc_package(url, &checksum);
result.map_err(|e| {
ExecuteLocalPackageError::BeforeExec(anyhow::anyhow!("error fetching {url}: {e}"))
})?;
if let Some(sp) = sp {
sp.clear();
}
}
let webc_dir = wasmer_registry::get_webc_dir();
let webc_install_path = webc_dir
.context("Error installing package: no webc dir")
.map_err(ExecuteLocalPackageError::BeforeExec)?
.join(checksum);
let mut r = r.clone();
r.path = webc_install_path;
r.execute().map_err(ExecuteLocalPackageError::DuringExec)
}

View File

@@ -24,6 +24,7 @@ pub mod c_gen;
pub mod cli;
#[cfg(feature = "debug")]
pub mod logging;
pub mod package_source;
pub mod store;
pub mod suggestions;
pub mod utils;

View File

@@ -0,0 +1,191 @@
//! Module for parsing and installing packages
use anyhow::Context;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use url::Url;
/// Source of a package
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum PackageSource {
/// Download from a URL
Url(Url),
/// Run a local file
File(String),
/// Download from a package
Package(wasmer_registry::Package),
}
impl Default for PackageSource {
fn default() -> Self {
PackageSource::File(String::new())
}
}
impl FromStr for PackageSource {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::parse(s)
}
}
impl PackageSource {
/// Parses a package source and transforms it to a URL or a File
pub fn parse(s: &str) -> Result<Self, String> {
// If the file is a http:// URL, run the URL
if let Ok(url) = url::Url::parse(s) {
if url.scheme() == "http" || url.scheme() == "https" {
return Ok(Self::Url(url));
}
}
Ok(match wasmer_registry::Package::from_str(s) {
Ok(o) => Self::Package(o),
Err(_) => Self::File(s.to_string()),
})
}
/// Downloads the package (if any) to the installation directory, returns the path
/// of the package directory (containing the wapm.toml)
pub fn download_and_get_filepath(&self) -> Result<PathBuf, anyhow::Error> {
let url = match self {
Self::File(f) => {
let path = Path::new(&f).to_path_buf();
return if path.exists() {
Ok(path)
} else {
Err(anyhow::anyhow!(
"invalid package name, could not find file {f}"
))
};
}
Self::Url(u) => {
if let Some(path) = wasmer_registry::Package::is_url_already_installed(u) {
return Ok(path);
} else {
u.clone()
}
}
Self::Package(p) => {
let package_path = Path::new(&p.file()).to_path_buf();
if package_path.exists() {
return Ok(package_path);
} else if let Some(path) = p.already_installed() {
return Ok(path);
} else {
p.url()?
}
}
};
let extra = if let Self::Package(p) = self {
format!(", file {} does not exist either", p.file())
} else {
String::new()
};
let mut sp = start_spinner(format!("Installing package {url} ..."));
let opt_path = wasmer_registry::install_package(&url);
if let Some(sp) = sp.take() {
use std::io::Write;
sp.clear();
let _ = std::io::stdout().flush();
}
let path = opt_path
.with_context(|| anyhow::anyhow!("could not install package from URL {url}{extra}"))?;
Ok(path)
}
}
fn start_spinner(msg: String) -> Option<spinoff::Spinner> {
if !isatty::stdout_isatty() {
return None;
}
#[cfg(target_os = "windows")]
{
use colored::control;
let _ = control::set_virtual_terminal(true);
}
Some(spinoff::Spinner::new(
spinoff::Spinners::Dots,
msg,
spinoff::Color::White,
))
}
#[test]
fn test_package_source() {
assert_eq!(
PackageSource::parse("registry.wapm.io/graphql/python/python").unwrap(),
PackageSource::File("registry.wapm.io/graphql/python/python".to_string()),
);
assert_eq!(
PackageSource::parse("/absolute/path/test.wasm").unwrap(),
PackageSource::File("/absolute/path/test.wasm".to_string()),
);
assert_eq!(
PackageSource::parse("C://absolute/path/test.wasm").unwrap(),
PackageSource::File("C://absolute/path/test.wasm".to_string()),
);
assert_eq!(
PackageSource::parse("namespace/name@latest").unwrap(),
PackageSource::Package(wasmer_registry::Package {
namespace: "namespace".to_string(),
name: "name".to_string(),
version: Some("latest".to_string()),
})
);
assert_eq!(
PackageSource::parse("namespace/name@latest:command").unwrap(),
PackageSource::File("namespace/name@latest:command".to_string()),
);
assert_eq!(
PackageSource::parse("namespace/name@1.0.2").unwrap(),
PackageSource::Package(wasmer_registry::Package {
namespace: "namespace".to_string(),
name: "name".to_string(),
version: Some("1.0.2".to_string()),
})
);
assert_eq!(
PackageSource::parse("namespace/name@1.0.2-rc.2").unwrap(),
PackageSource::Package(wasmer_registry::Package {
namespace: "namespace".to_string(),
name: "name".to_string(),
version: Some("1.0.2-rc.2".to_string()),
})
);
assert_eq!(
PackageSource::parse("namespace/name").unwrap(),
PackageSource::Package(wasmer_registry::Package {
namespace: "namespace".to_string(),
name: "name".to_string(),
version: None,
})
);
assert_eq!(
PackageSource::parse("https://wapm.io/syrusakbary/python").unwrap(),
PackageSource::Url(url::Url::parse("https://wapm.io/syrusakbary/python").unwrap()),
);
assert_eq!(
PackageSource::parse("command").unwrap(),
PackageSource::File("command".to_string()),
);
assert_eq!(
PackageSource::parse("python@latest").unwrap(),
PackageSource::File("python@latest".to_string()),
);
}

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-compiler-cranelift"
version = "3.0.2"
version = "3.1.0"
description = "Cranelift compiler for Wasmer WebAssembly runtime"
categories = ["wasm"]
keywords = ["wasm", "webassembly", "compiler", "cranelift"]
@@ -12,8 +12,8 @@ readme = "README.md"
edition = "2018"
[dependencies]
wasmer-compiler = { path = "../compiler", version = "=3.0.2", features = ["translator", "compiler"], default-features = false }
wasmer-types = { path = "../types", version = "=3.0.2", default-features = false, features = ["std"] }
wasmer-compiler = { path = "../compiler", version = "=3.1.0", features = ["translator", "compiler"], default-features = false }
wasmer-types = { path = "../types", version = "=3.1.0", default-features = false, features = ["std"] }
cranelift-entity = { version = "0.86.1", default-features = false }
cranelift-codegen = { version = "0.86.1", default-features = false, features = ["x86", "arm64"] }
cranelift-frontend = { version = "0.86.1", default-features = false }

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-compiler-llvm"
version = "3.0.2"
version = "3.1.0"
description = "LLVM compiler for Wasmer WebAssembly runtime"
categories = ["wasm"]
keywords = ["wasm", "webassembly", "compiler", "llvm"]
@@ -12,11 +12,11 @@ readme = "README.md"
edition = "2018"
[dependencies]
wasmer-compiler = { path = "../compiler", version = "=3.0.2", features = [
wasmer-compiler = { path = "../compiler", version = "=3.1.0", features = [
"translator", "compiler"
] }
wasmer-vm = { path = "../vm", version = "=3.0.2" }
wasmer-types = { path = "../types", version = "=3.0.2" }
wasmer-vm = { path = "../vm", version = "=3.1.0" }
wasmer-types = { path = "../types", version = "=3.1.0" }
target-lexicon = { version = "0.12.2", default-features = false }
smallvec = "1.6"
object = { version = "0.28.3", default-features = false, features = ["read"] }

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-compiler-singlepass"
version = "3.0.2"
version = "3.1.0"
description = "Singlepass compiler for Wasmer WebAssembly runtime"
categories = ["wasm"]
keywords = ["wasm", "webassembly", "compiler", "singlepass"]
@@ -12,8 +12,8 @@ readme = "README.md"
edition = "2018"
[dependencies]
wasmer-compiler = { path = "../compiler", version = "=3.0.2", features = ["translator", "compiler"], default-features = false }
wasmer-types = { path = "../types", version = "=3.0.2", default-features = false, features = ["std"] }
wasmer-compiler = { path = "../compiler", version = "=3.1.0", features = ["translator", "compiler"], default-features = false }
wasmer-types = { path = "../types", version = "=3.1.0", default-features = false, features = ["std"] }
hashbrown = { version = "0.11", optional = true }
gimli = { version = "0.26", optional = true }
enumset = "1.0.2"

View File

@@ -1303,6 +1303,12 @@ impl EmitterARM64 for Assembler {
let masked = 0xffff & (val >> offset);
if (masked << offset) == val {
dynasm!(self ; movz X(dst), masked as u32, LSL offset);
} else if val >> 16 == 0xffff_ffff_ffff {
let val: u16 = !((val & 0xffff) as u16);
dynasm!(self ; movn X(dst), val as u32);
} else if val >> 16 == 0xffff {
let val: u16 = !((val & 0xffff) as u16);
dynasm!(self ; movn W(dst), val as u32);
} else {
dynasm!(self ; movz W(dst), (val&0xffff) as u32);
let val = val >> 16;
@@ -1336,13 +1342,13 @@ impl EmitterARM64 for Assembler {
let src1 = src1.into_index() as u32;
let src2 = src2.into_index() as u32;
let dst = dst.into_index() as u32;
dynasm!(self ; add X(dst), X(src1), X(src2));
dynasm!(self ; add X(dst), X(src1), X(src2), UXTX);
}
(Size::S32, Location::GPR(src1), Location::GPR(src2), Location::GPR(dst)) => {
let src1 = src1.into_index() as u32;
let src2 = src2.into_index() as u32;
let dst = dst.into_index() as u32;
dynasm!(self ; add W(dst), W(src1), W(src2));
dynasm!(self ; add W(dst), W(src1), W(src2), UXTX);
}
(Size::S64, Location::GPR(src1), Location::Imm8(imm), Location::GPR(dst))
| (Size::S64, Location::Imm8(imm), Location::GPR(src1), Location::GPR(dst)) => {
@@ -1406,13 +1412,13 @@ impl EmitterARM64 for Assembler {
let src1 = src1.into_index() as u32;
let src2 = src2.into_index() as u32;
let dst = dst.into_index() as u32;
dynasm!(self ; sub X(dst), X(src1), X(src2));
dynasm!(self ; sub X(dst), X(src1), X(src2), UXTX);
}
(Size::S32, Location::GPR(src1), Location::GPR(src2), Location::GPR(dst)) => {
let src1 = src1.into_index() as u32;
let src2 = src2.into_index() as u32;
let dst = dst.into_index() as u32;
dynasm!(self ; sub W(dst), W(src1), W(src2));
dynasm!(self ; sub W(dst), W(src1), W(src2), UXTX);
}
(Size::S64, Location::GPR(src1), Location::Imm8(imm), Location::GPR(dst)) => {
let src1 = src1.into_index() as u32;
@@ -3257,24 +3263,17 @@ pub fn gen_std_trampoline_arm64(
#[allow(clippy::single_match)]
match calling_convention {
CallingConvention::AppleAarch64 => {
match sz {
Size::S8 => (),
Size::S16 => {
if caller_stack_offset & 1 != 0 {
caller_stack_offset = (caller_stack_offset + 1) & !1;
}
}
Size::S32 => {
if caller_stack_offset & 3 != 0 {
caller_stack_offset = (caller_stack_offset + 3) & !3;
}
}
Size::S64 => {
if caller_stack_offset & 7 != 0 {
caller_stack_offset = (caller_stack_offset + 7) & !7;
}
}
let sz = 1
<< match sz {
Size::S8 => 0,
Size::S16 => 1,
Size::S32 => 2,
Size::S64 => 3,
};
// align first
if sz > 1 && caller_stack_offset & (sz - 1) != 0 {
caller_stack_offset = (caller_stack_offset + (sz - 1)) & !(sz - 1);
}
}
_ => (),
};
@@ -3291,11 +3290,12 @@ pub fn gen_std_trampoline_arm64(
)?;
match calling_convention {
CallingConvention::AppleAarch64 => {
caller_stack_offset += match sz {
Size::S8 => 1,
Size::S16 => 2,
Size::S32 => 4,
Size::S64 => 8,
caller_stack_offset += 1
<< match sz {
Size::S8 => 0,
Size::S16 => 1,
Size::S32 => 2,
Size::S64 => 3,
};
}
_ => {

View File

@@ -1760,6 +1760,15 @@ impl Machine for MachineARM64 {
.emit_stur(Size::S64, location, GPR::X29, -stack_offset)?;
} else {
let tmp = GPR::X17;
if stack_offset < 0x1_0000 {
self.assembler
.emit_mov_imm(Location::GPR(tmp), (-stack_offset as i64) as u64)?;
self.assembler.emit_str(
Size::S64,
location,
Location::Memory2(GPR::X29, tmp, Multiplier::One, 0),
)?;
} else {
self.assembler
.emit_mov_imm(Location::GPR(tmp), (stack_offset as i64) as u64)?;
self.assembler.emit_sub(
@@ -1771,6 +1780,7 @@ impl Machine for MachineARM64 {
self.assembler
.emit_str(Size::S64, location, Location::GPR(tmp))?;
}
}
match location {
Location::GPR(x) => self.emit_unwind_op(UnwindOps::SaveRegister {
reg: x.to_dwarf(),
@@ -1809,18 +1819,19 @@ impl Machine for MachineARM64 {
6 => Location::GPR(GPR::X6),
7 => Location::GPR(GPR::X7),
_ => {
let sz = match sz {
let sz = 1
<< match sz {
Size::S8 => 0,
Size::S16 => 1,
Size::S32 => 2,
Size::S64 => 3,
};
// align first
if sz > 1 && *stack_args & !((1 << sz) - 1) != 0 {
*stack_args = (*stack_args + ((1 << sz) - 1)) & !((1 << sz) - 1);
if sz > 1 && *stack_args & (sz - 1) != 0 {
*stack_args = (*stack_args + (sz - 1)) & !(sz - 1);
}
let loc = Location::Memory(GPR::XzrSp, *stack_args as i32);
*stack_args += 1 << sz;
*stack_args += sz;
loc
}
},
@@ -1860,18 +1871,19 @@ impl Machine for MachineARM64 {
6 => Location::GPR(GPR::X6),
7 => Location::GPR(GPR::X7),
_ => {
let sz = match sz {
let sz = 1
<< match sz {
Size::S8 => 0,
Size::S16 => 1,
Size::S32 => 2,
Size::S64 => 3,
};
// align first
if sz > 1 && *stack_args & !((1 << sz) - 1) != 0 {
*stack_args = (*stack_args + ((1 << sz) - 1)) & !((1 << sz) - 1);
if sz > 1 && *stack_args & (sz - 1) != 0 {
*stack_args = (*stack_args + (sz - 1)) & !(sz - 1);
}
let loc = Location::Memory(GPR::X29, 16 * 2 + *stack_args as i32);
*stack_args += 1 << sz;
*stack_args += sz;
loc
}
},

View File

@@ -45,7 +45,7 @@ impl AssemblerX64 {
Some(CpuFeature::SSE42)
} else {
return Err(CompileError::UnsupportedTarget(
"x86_64 without AVX or SSE 4.2".to_string(),
"x86_64 without AVX or SSE 4.2, use -m avx to enable".to_string(),
));
}
};

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-compiler"
version = "3.0.2"
version = "3.1.0"
description = "Base compiler abstraction for Wasmer WebAssembly runtime"
categories = ["wasm", "no-std"]
keywords = ["wasm", "webassembly", "compiler"]
@@ -11,8 +11,8 @@ readme = "README.md"
edition = "2018"
[dependencies]
wasmer-types = { path = "../types", version = "=3.0.2", default-features = false }
wasmer-object = { path = "../object", version = "=3.0.2", optional = true }
wasmer-types = { path = "../types", version = "=3.1.0", default-features = false }
wasmer-object = { path = "../object", version = "=3.1.0", optional = true }
wasmparser = { version = "0.83", optional = true, default-features = false }
enumset = "1.0.2"
hashbrown = { version = "0.11", optional = true }
@@ -32,7 +32,7 @@ leb128 = "0.2"
enum-iterator = "0.7.0"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
wasmer-vm = { path = "../vm", version = "=3.0.2" }
wasmer-vm = { path = "../vm", version = "=3.1.0" }
region = { version = "3.0" }
[target.'cfg(target_os = "windows")'.dependencies]

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-derive"
version = "3.0.2"
version = "3.1.0"
description = "Wasmer derive macros"
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
repository = "https://github.com/wasmerio/wasmer"

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-emscripten"
version = "3.0.2"
version = "3.1.0"
description = "Emscripten implementation library for Wasmer WebAssembly runtime"
categories = ["wasm", "os"]
keywords = ["wasm", "webassembly", "abi", "emscripten", "posix"]
@@ -16,8 +16,8 @@ lazy_static = "1.4"
libc = "^0.2"
log = "0.4"
time = { version = "0.2", features = ["std"] }
wasmer = { path = "../api", version = "=3.0.2", default-features = false, features = ["sys", "compiler"] }
wasmer-types = { path = "../types", version = "=3.0.2" }
wasmer = { path = "../api", version = "=3.1.0", default-features = false, features = ["sys", "compiler"] }
wasmer-types = { path = "../types", version = "=3.1.0" }
[target.'cfg(windows)'.dependencies]
getrandom = "0.2"

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-middlewares"
version = "3.0.2"
version = "3.1.0"
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
description = "A collection of various useful middlewares"
license = "MIT OR Apache-2.0 WITH LLVM-exception"
@@ -11,12 +11,12 @@ readme = "README.md"
edition = "2018"
[dependencies]
wasmer = { path = "../api", version = "=3.0.2", default-features = false, features = ["compiler"] }
wasmer-types = { path = "../types", version = "=3.0.2" }
wasmer-vm = { path = "../vm", version = "=3.0.2" }
wasmer = { path = "../api", version = "=3.1.0", default-features = false, features = ["compiler"] }
wasmer-types = { path = "../types", version = "=3.1.0" }
wasmer-vm = { path = "../vm", version = "=3.1.0" }
[dev-dependencies]
wasmer = { path = "../api", version = "=3.0.2", features = ["compiler"] }
wasmer = { path = "../api", version = "=3.1.0", features = ["compiler"] }
[badges]
maintenance = { status = "actively-developed" }

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-object"
version = "3.0.2"
version = "3.1.0"
description = "Wasmer Native Object generator"
categories = ["wasm"]
keywords = ["wasm", "webassembly"]
@@ -11,6 +11,6 @@ readme = "README.md"
edition = "2018"
[dependencies]
wasmer-types = { path = "../types", version = "=3.0.2" }
wasmer-types = { path = "../types", version = "=3.1.0" }
object = { version = "0.28.3", default-features = false, features = ["write"] }
thiserror = "1.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-registry"
version = "3.0.2"
version = "3.1.0"
edition = "2021"
license = "MIT"
description = "Crate to interact with the wasmer registry (wapm.io), download packages, etc."
@@ -30,3 +30,7 @@ hex = "0.4.3"
tokio = "1.21.2"
tempdir = "0.3.7"
log = "0.4.17"
regex = "1.7.0"
fs_extra = "1.2.0"
filetime = "0.2.19"
tldextract = "0.6.0"

View File

@@ -13,23 +13,21 @@ use anyhow::Context;
use core::ops::Range;
use reqwest::header::{ACCEPT, RANGE};
use std::fmt;
use std::io::Write;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::time::Duration;
use std::{
collections::BTreeMap,
fmt::{Display, Formatter},
};
use url::Url;
pub mod config;
pub mod graphql;
pub mod login;
pub mod package;
pub mod queries;
pub mod utils;
pub use crate::{
config::{format_graphql, PartialWapmConfig},
package::Package,
queries::get_bindings_query::ProgrammingLanguage,
};
@@ -49,31 +47,23 @@ pub struct PackageDownloadInfo {
pub fn get_package_local_dir(
#[cfg(test)] test_name: &str,
registry_host: &str,
name: &str,
url: &str,
version: &str,
) -> Result<PathBuf, String> {
if !name.contains('/') {
return Err(format!(
"package name has to be in the format namespace/package: {name:?}"
));
}
let (namespace, name) = name
.split_once('/')
.ok_or_else(|| format!("missing namespace / name for {name:?}"))?;
) -> Option<PathBuf> {
#[cfg(test)]
let global_install_dir = get_global_install_dir(test_name, registry_host);
let checkouts_dir = get_checkouts_dir(test_name)?;
#[cfg(not(test))]
let global_install_dir = get_global_install_dir(registry_host);
let install_dir = global_install_dir.ok_or_else(|| format!("no install dir for {name:?}"))?;
Ok(install_dir.join(namespace).join(name).join(version))
let checkouts_dir = get_checkouts_dir()?;
let url_hash = Package::hash_url(url);
let dir = checkouts_dir.join(format!("{url_hash}@{version}"));
Some(dir)
}
pub fn try_finding_local_command(#[cfg(test)] test_name: &str, cmd: &str) -> Option<LocalPackage> {
#[cfg(test)]
let local_packages = get_all_local_packages(test_name, None);
let local_packages = get_all_local_packages(test_name);
#[cfg(not(test))]
let local_packages = get_all_local_packages(None);
let local_packages = get_all_local_packages();
for p in local_packages {
#[cfg(not(test))]
let commands = p.get_commands();
@@ -92,24 +82,12 @@ pub struct LocalPackage {
pub registry: String,
pub name: String,
pub version: String,
pub path: PathBuf,
}
impl LocalPackage {
pub fn get_path(&self, #[cfg(test)] test_name: &str) -> Result<PathBuf, String> {
let host = url::Url::parse(&self.registry)
.ok()
.and_then(|o| o.host_str().map(|s| s.to_string()))
.unwrap_or_else(|| self.registry.clone());
#[cfg(test)]
{
get_package_local_dir(test_name, &host, &self.name, &self.version)
}
#[cfg(not(test))]
{
get_package_local_dir(&host, &self.name, &self.version)
}
Ok(self.path.clone())
}
pub fn get_commands(&self, #[cfg(test)] test_name: &str) -> Result<Vec<String>, String> {
#[cfg(not(test))]
@@ -149,9 +127,20 @@ pub fn get_executable_file_from_path(
Some(s) => commands.iter().find(|c| c.get_name() == s).ok_or_else(|| {
anyhow::anyhow!("Cannot run {name}@{version}: package has no command {s:?}")
})?,
None => commands.first().ok_or_else(|| {
anyhow::anyhow!("Cannot run {name}@{version}: package has no commands")
})?,
None => {
if commands.is_empty() {
Err(anyhow::anyhow!(
"Cannot run {name}@{version}: package has no commands"
))
} else if commands.len() == 1 {
Ok(&commands[0])
} else {
Err(anyhow::anyhow!(" -> wasmer run {name}@{version} --command-name={0}", commands.first().map(|f| f.get_name()).unwrap()))
.context(anyhow::anyhow!("{}", commands.iter().map(|c| format!("`{}`", c.get_name())).collect::<Vec<_>>().join(", ")))
.context(anyhow::anyhow!("You can run any of those by using the --command-name=COMMAND flag"))
.context(anyhow::anyhow!("The `{name}@{version}` package doesn't have a default entrypoint, but has multiple available commands:"))
}?
}
};
let module_name = entrypoint_module.get_module();
@@ -196,87 +185,58 @@ fn get_all_names_in_dir(dir: &PathBuf) -> Vec<(PathBuf, String)> {
}
/// Returns a list of all locally installed packages
pub fn get_all_local_packages(
#[cfg(test)] test_name: &str,
registry: Option<&str>,
) -> Vec<LocalPackage> {
pub fn get_all_local_packages(#[cfg(test)] test_name: &str) -> Vec<LocalPackage> {
let mut packages = Vec::new();
let registries = match registry {
Some(s) => vec![s.to_string()],
None => {
#[cfg(test)]
{
get_all_available_registries(test_name).unwrap_or_default()
}
#[cfg(not(test))]
{
get_all_available_registries().unwrap_or_default()
}
}
};
let mut registry_hosts = registries
.into_iter()
.filter_map(|s| url::Url::parse(&s).ok()?.host_str().map(|s| s.to_string()))
.collect::<Vec<_>>();
#[cfg(not(test))]
let checkouts_dir = get_checkouts_dir();
#[cfg(test)]
let checkouts_dir = get_checkouts_dir(test_name);
let mut registries_in_root_dir = checkouts_dir
.as_ref()
.map(get_all_names_in_dir)
.unwrap_or_default()
.into_iter()
.filter_map(|(path, p)| if path.is_dir() { Some(p) } else { None })
.collect();
registry_hosts.append(&mut registries_in_root_dir);
registry_hosts.sort();
registry_hosts.dedup();
for host in registry_hosts {
#[cfg(not(test))]
let global_install_dir = get_global_install_dir(&host);
#[cfg(test)]
let global_install_dir = get_global_install_dir(test_name, &host);
let root_dir = match global_install_dir {
Some(o) => o,
None => continue,
let checkouts_dir = match checkouts_dir {
Some(s) => s,
None => return packages,
};
for (username_path, user_name) in get_all_names_in_dir(&root_dir) {
for (package_path, package_name) in get_all_names_in_dir(&username_path) {
for (version_path, package_version) in get_all_names_in_dir(&package_path) {
let _ = match std::fs::read_to_string(version_path.join("wapm.toml")) {
for (path, url_hash_with_version) in get_all_names_in_dir(&checkouts_dir) {
let s = match std::fs::read_to_string(path.join("wapm.toml")) {
Ok(o) => o,
Err(_) => continue,
};
let manifest = match wapm_toml::Manifest::parse(&s) {
Ok(o) => o,
Err(_) => continue,
};
let url_hash = match url_hash_with_version.split('@').next() {
Some(s) => s,
None => continue,
};
let package =
Url::parse(&Package::unhash_url(url_hash)).map(|s| s.origin().ascii_serialization());
let host = match package {
Ok(s) => s,
Err(_) => continue,
};
packages.push(LocalPackage {
registry: host.clone(),
name: format!("{user_name}/{package_name}"),
version: package_version,
registry: host,
name: manifest.package.name,
version: manifest.package.version.to_string(),
path,
});
}
}
}
}
packages
}
pub fn get_local_package(
#[cfg(test)] test_name: &str,
registry: Option<&str>,
name: &str,
version: Option<&str>,
) -> Option<LocalPackage> {
#[cfg(not(test))]
let local_packages = get_all_local_packages(registry);
let local_packages = get_all_local_packages();
#[cfg(test)]
let local_packages = get_all_local_packages(test_name, registry);
let local_packages = get_all_local_packages(test_name);
local_packages
.iter()
@@ -309,7 +269,7 @@ pub fn query_command_from_registry(
});
let response: get_package_by_command_query::ResponseData = execute_query(registry_url, "", &q)
.map_err(|e| format!("Error sending GetPackageByCommandQuery:  {e}"))?;
.map_err(|e| format!("Error sending GetPackageByCommandQuery: {e}"))?;
let command = response
.get_command
@@ -342,7 +302,7 @@ pub enum QueryPackageError {
}
impl fmt::Display for QueryPackageError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
QueryPackageError::ErrorSendingQuery(q) => write!(f, "error sending query: {q}"),
QueryPackageError::NoPackageFound { name, version } => {
@@ -380,194 +340,6 @@ pub enum GetIfPackageHasNewVersionResult {
},
}
#[test]
fn test_get_if_package_has_new_version() {
const TEST_NAME: &str = "test_get_if_package_has_new_version";
let fake_registry = "https://h0.com";
let fake_name = "namespace0/project1";
let fake_version = "1.0.0";
let package_path = get_package_local_dir(TEST_NAME, "h0.com", fake_name, fake_version).unwrap();
let _ = std::fs::remove_file(&package_path.join("wapm.toml"));
let _ = std::fs::remove_file(&package_path.join("wapm.toml"));
let r1 = get_if_package_has_new_version(
TEST_NAME,
fake_registry,
"namespace0/project1",
Some(fake_version.to_string()),
Duration::from_secs(5 * 60),
);
assert_eq!(
r1.unwrap(),
GetIfPackageHasNewVersionResult::PackageNotInstalledYet {
registry_url: fake_registry.to_string(),
namespace: "namespace0".to_string(),
name: "project1".to_string(),
version: Some(fake_version.to_string()),
}
);
let package_path = get_package_local_dir(TEST_NAME, "h0.com", fake_name, fake_version).unwrap();
std::fs::create_dir_all(&package_path).unwrap();
std::fs::write(&package_path.join("wapm.toml"), b"").unwrap();
let r1 = get_if_package_has_new_version(
TEST_NAME,
fake_registry,
"namespace0/project1",
Some(fake_version.to_string()),
Duration::from_secs(5 * 60),
);
assert_eq!(
r1.unwrap(),
GetIfPackageHasNewVersionResult::UseLocalAlreadyInstalled {
registry_host: "h0.com".to_string(),
namespace: "namespace0".to_string(),
name: "project1".to_string(),
version: fake_version.to_string(),
path: package_path,
}
);
}
/// Returns true if a package has a newer version
///
/// Also returns true if the package is not installed yet.
pub fn get_if_package_has_new_version(
#[cfg(test)] test_name: &str,
registry_url: &str,
name: &str,
version: Option<String>,
max_timeout: Duration,
) -> Result<GetIfPackageHasNewVersionResult, String> {
let host = match url::Url::parse(registry_url) {
Ok(o) => match o.host_str().map(|s| s.to_string()) {
Some(s) => s,
None => return Err(format!("invalid host: {registry_url}")),
},
Err(_) => return Err(format!("invalid host: {registry_url}")),
};
let (namespace, name) = name
.split_once('/')
.ok_or_else(|| format!("missing namespace / name for {name:?}"))?;
#[cfg(not(test))]
let global_install_dir = get_global_install_dir(&host);
#[cfg(test)]
let global_install_dir = get_global_install_dir(test_name, &host);
let package_dir = global_install_dir.map(|path| path.join(namespace).join(name));
let package_dir = match package_dir {
Some(s) => s,
None => {
return Ok(GetIfPackageHasNewVersionResult::PackageNotInstalledYet {
registry_url: registry_url.to_string(),
namespace: namespace.to_string(),
name: name.to_string(),
version,
})
}
};
// if version is specified: look if that specific version exists
if let Some(s) = version.as_ref() {
let installed_path = package_dir.join(s).join("wapm.toml");
if installed_path.exists() {
return Ok(GetIfPackageHasNewVersionResult::UseLocalAlreadyInstalled {
registry_host: host,
namespace: namespace.to_string(),
name: name.to_string(),
version: s.clone(),
path: package_dir.join(s),
});
} else {
return Ok(GetIfPackageHasNewVersionResult::PackageNotInstalledYet {
registry_url: registry_url.to_string(),
namespace: namespace.to_string(),
name: name.to_string(),
version: Some(s.clone()),
});
}
}
// version has not been explicitly specified: check if any package < duration exists
let read_dir = match std::fs::read_dir(&package_dir) {
Ok(o) => o,
Err(_) => {
return Ok(GetIfPackageHasNewVersionResult::PackageNotInstalledYet {
registry_url: registry_url.to_string(),
namespace: namespace.to_string(),
name: name.to_string(),
version,
});
}
};
// all installed versions of this package
let all_installed_versions = read_dir
.filter_map(|entry| {
let entry = entry.ok()?;
let version = semver::Version::parse(entry.file_name().to_str()?).ok()?;
let modified = entry.metadata().ok()?.modified().ok()?;
let older_than_timeout = modified.elapsed().ok()? > max_timeout;
Some((version, older_than_timeout))
})
.collect::<Vec<_>>();
if all_installed_versions.is_empty() {
// package not installed yet
Ok(GetIfPackageHasNewVersionResult::PackageNotInstalledYet {
registry_url: registry_url.to_string(),
namespace: namespace.to_string(),
name: name.to_string(),
version,
})
} else if all_installed_versions
.iter()
.all(|(_, older_than_timeout)| *older_than_timeout)
{
// all packages are older than the timeout: there might be a new package available
return Ok(GetIfPackageHasNewVersionResult::LocalVersionMayBeOutdated {
registry_host: registry_url.to_string(),
namespace: namespace.to_string(),
name: name.to_string(),
installed_versions: all_installed_versions
.iter()
.map(|(key, old)| (format!("{key}"), *old))
.collect::<Vec<_>>(),
});
} else {
// return the package that was younger than timeout
let younger_than_timeout_version = all_installed_versions
.iter()
.find(|(_, older_than_timeout)| !older_than_timeout)
.unwrap();
let version = format!("{}", younger_than_timeout_version.0);
let installed_path = package_dir.join(&version).join("wapm.toml");
if installed_path.exists() {
Ok(GetIfPackageHasNewVersionResult::UseLocalAlreadyInstalled {
registry_host: host,
namespace: namespace.to_string(),
name: name.to_string(),
version: version.clone(),
path: package_dir.join(&version),
})
} else {
Ok(GetIfPackageHasNewVersionResult::PackageNotInstalledYet {
registry_url: registry_url.to_string(),
namespace: namespace.to_string(),
name: name.to_string(),
version: None,
})
}
}
}
/// Returns the download info of the packages, on error returns all the available packages
/// i.e. (("foo/python", "wapm.io"), ("bar/python" "wapm.io")))
pub fn query_package_from_registry(
@@ -592,9 +364,7 @@ pub fn query_package_from_registry(
})?;
let v = response.package_version.as_ref().ok_or_else(|| {
QueryPackageError::ErrorSendingQuery(format!(
"Invalid response for crate {name:?}: no package version: {response:#?}"
))
QueryPackageError::ErrorSendingQuery(format!("no package version for {name:?}"))
})?;
let manifest = toml::from_str::<wapm_toml::Manifest>(&v.manifest).map_err(|e| {
@@ -766,139 +536,67 @@ where
Ok(())
}
/// Given a triple of [registry, name, version], downloads and installs the
/// .tar.gz if it doesn't yet exist, returns the (package dir, entrypoint .wasm file path)
pub fn install_package(
#[cfg(test)] test_name: &str,
registry: Option<&str>,
name: &str,
version: Option<&str>,
package_download_info: Option<PackageDownloadInfo>,
force_install: bool,
) -> Result<(LocalPackage, PathBuf), String> {
let package_info = match package_download_info {
Some(s) => s,
None => {
let registries = match registry {
Some(s) => vec![s.to_string()],
None => {
#[cfg(test)]
{
get_all_available_registries(test_name)?
}
#[cfg(not(test))]
{
get_all_available_registries()?
}
}
};
let mut url_of_package = None;
/// Installs the .tar.gz if it doesn't yet exist, returns the
/// (package dir, entrypoint .wasm file path)
pub fn install_package(#[cfg(test)] test_name: &str, url: &Url) -> Result<PathBuf, anyhow::Error> {
use fs_extra::dir::copy;
let version_str = match version {
None => name.to_string(),
Some(v) => format!("{name}@{v}"),
};
let tempdir = tempdir::TempDir::new("download")
.map_err(|e| anyhow::anyhow!("could not create download temp dir: {e}"))?;
let registries_searched = registries
.iter()
.filter_map(|s| url::Url::parse(s).ok())
.filter_map(|s| Some(s.host_str()?.to_string()))
.collect::<Vec<_>>();
let mut errors = BTreeMap::new();
for r in registries.iter() {
if !force_install {
#[cfg(not(test))]
let package_has_new_version = get_if_package_has_new_version(
r,
name,
version.map(|s| s.to_string()),
Duration::from_secs(60 * 5),
)?;
#[cfg(test)]
let package_has_new_version = get_if_package_has_new_version(
test_name,
r,
name,
version.map(|s| s.to_string()),
Duration::from_secs(60 * 5),
)?;
if let GetIfPackageHasNewVersionResult::UseLocalAlreadyInstalled {
registry_host,
namespace,
name,
version,
path,
} = package_has_new_version
{
return Ok((
LocalPackage {
registry: registry_host,
name: format!("{namespace}/{name}"),
version,
},
path,
));
}
}
match query_package_from_registry(r, name, version) {
Ok(o) => {
url_of_package = Some((r, o));
break;
}
Err(e) => {
errors.insert(r.clone(), e);
}
}
}
let errors = errors
.into_iter()
.map(|(registry, e)| format!(" {registry}: {e}"))
.collect::<Vec<_>>()
.join("\r\n");
let (_, package_info) = url_of_package.ok_or_else(|| {
format!("Package {version_str} not found in registries {registries_searched:?}.\r\n\r\nErrors:\r\n\r\n{errors}")
let target_targz_path = tempdir.path().join("package.tar.gz");
let unpacked_targz_path = tempdir.path().join("package");
std::fs::create_dir_all(&unpacked_targz_path).map_err(|e| {
anyhow::anyhow!(
"could not create dir {}: {e}",
unpacked_targz_path.display()
)
})?;
package_info
}
};
get_targz_bytes(url, None, Some(target_targz_path.clone()))
.map_err(|e| anyhow::anyhow!("failed to download {url}: {e}"))?;
let host = url::Url::parse(&package_info.registry)
.map_err(|e| format!("invalid url: {}: {e}", package_info.registry))?
.host_str()
.ok_or_else(|| format!("invalid url: {}", package_info.registry))?
.to_string();
try_unpack_targz(
target_targz_path.as_path(),
unpacked_targz_path.as_path(),
false,
)
.with_context(|| anyhow::anyhow!("Could not unpack file downloaded from {url}"))?;
// read {unpacked}/wapm.toml to get the name + version number
let toml_path = unpacked_targz_path.join("wapm.toml");
let toml = std::fs::read_to_string(&toml_path)
.map_err(|e| anyhow::anyhow!("error reading {}: {e}", toml_path.display()))?;
let toml_parsed = toml::from_str::<wapm_toml::Manifest>(&toml)
.map_err(|e| anyhow::anyhow!("error parsing {}: {e}", toml_path.display()))?;
let version = toml_parsed.package.version.to_string();
#[cfg(test)]
let dir = get_package_local_dir(
test_name,
&host,
&package_info.package,
&package_info.version,
)?;
let checkouts_dir = crate::get_checkouts_dir(test_name);
#[cfg(not(test))]
let dir = get_package_local_dir(&host, &package_info.package, &package_info.version)?;
let checkouts_dir = crate::get_checkouts_dir();
let version = package_info.version;
let name = package_info.package;
let checkouts_dir = checkouts_dir.ok_or_else(|| anyhow::anyhow!("no checkouts dir"))?;
if !dir.join("wapm.toml").exists() || force_install {
download_and_unpack_targz(&package_info.url, &dir, false).map_err(|e| format!("{e}"))?;
}
let installation_path =
checkouts_dir.join(format!("{}@{version}", Package::hash_url(url.as_ref())));
Ok((
LocalPackage {
registry: package_info.registry,
name,
version,
},
dir,
))
std::fs::create_dir_all(&installation_path)
.map_err(|e| anyhow::anyhow!("could not create installation path for {url}: {e}"))?;
let mut options = fs_extra::dir::CopyOptions::new();
options.content_only = true;
options.overwrite = true;
copy(&unpacked_targz_path, &installation_path, &options)?;
#[cfg(not(target_os = "wasi"))]
let _ = filetime::set_file_mtime(
installation_path.join("wapm.toml"),
filetime::FileTime::now(),
);
Ok(installation_path)
}
pub fn whoami(
@@ -1032,6 +730,7 @@ async fn install_webc_package_inner(
let builder = reqwest::Client::builder();
let builder = crate::graphql::proxy::maybe_set_up_proxy(builder)?;
builder
.redirect(reqwest::redirect::Policy::limited(10))
.build()
.map_err(|e| anyhow::anyhow!("{e}"))
.context("install_webc_package: failed to build reqwest Client")?
@@ -1129,18 +828,18 @@ pub fn get_checksum_hash(bytes: &[u8]) -> String {
while checksum.last().copied() == Some(0) {
checksum.pop();
}
hex::encode(&checksum)
hex::encode(&checksum).chars().take(64).collect()
}
/// Returns the checksum of the .webc file, so that we can check whether the
/// file is already installed before downloading it
pub fn get_remote_webc_checksum(url: &Url) -> Result<String, anyhow::Error> {
let request_max_bytes = webc::WebC::get_signature_offset_start() + 4 + 1024 + 8 + 8;
let data = get_webc_bytes(url, Some(0..request_max_bytes))
.with_context(|| format!("get_webc_bytes failed on {url}"))?;
let data = get_webc_bytes(url, Some(0..request_max_bytes), None)
.with_context(|| anyhow::anyhow!("note: use --registry to change the registry URL"))?
.unwrap();
let checksum = webc::WebC::get_checksum_bytes(&data)
.map_err(|e| anyhow::anyhow!("{e}"))
.context("get_checksum_bytes failed")?
.map_err(|e| anyhow::anyhow!("{e}"))?
.to_vec();
Ok(get_checksum_hash(&checksum))
}
@@ -1150,7 +849,7 @@ pub fn get_remote_webc_checksum(url: &Url) -> Result<String, anyhow::Error> {
pub fn get_remote_webc_manifest(url: &Url) -> Result<RemoteWebcInfo, anyhow::Error> {
// Request up unti manifest size / manifest len
let request_max_bytes = webc::WebC::get_signature_offset_start() + 4 + 1024 + 8 + 8;
let data = get_webc_bytes(url, Some(0..request_max_bytes))?;
let data = get_webc_bytes(url, Some(0..request_max_bytes), None)?.unwrap();
let checksum = webc::WebC::get_checksum_bytes(&data)
.map_err(|e| anyhow::anyhow!("{e}"))
.context("WebC::get_checksum_bytes failed")?
@@ -1160,7 +859,8 @@ pub fn get_remote_webc_manifest(url: &Url) -> Result<RemoteWebcInfo, anyhow::Err
let (manifest_start, manifest_len) = webc::WebC::get_manifest_offset_size(&data)
.map_err(|e| anyhow::anyhow!("{e}"))
.context("WebC::get_manifest_offset_size failed")?;
let data_with_manifest = get_webc_bytes(url, Some(0..manifest_start + manifest_len))?;
let data_with_manifest =
get_webc_bytes(url, Some(0..manifest_start + manifest_len), None)?.unwrap();
let manifest = webc::WebC::get_manifest(&data_with_manifest)
.map_err(|e| anyhow::anyhow!("{e}"))
.context("WebC::get_manifest failed")?;
@@ -1170,39 +870,113 @@ pub fn get_remote_webc_manifest(url: &Url) -> Result<RemoteWebcInfo, anyhow::Err
})
}
fn setup_webc_client(url: &Url) -> Result<reqwest::blocking::RequestBuilder, anyhow::Error> {
fn setup_client(
url: &Url,
application_type: &'static str,
) -> Result<reqwest::blocking::RequestBuilder, anyhow::Error> {
let client = {
let builder = reqwest::blocking::Client::builder();
let builder = crate::graphql::proxy::maybe_set_up_proxy_blocking(builder)
.context("setup_webc_client")?;
builder
.redirect(reqwest::redirect::Policy::limited(10))
.build()
.map_err(|e| anyhow::anyhow!("{e}"))
.context("setup_webc_client: builder.build() failed")?
};
Ok(client.get(url.clone()).header(ACCEPT, "application/webc"))
Ok(client.get(url.clone()).header(ACCEPT, application_type))
}
fn get_webc_bytes(url: &Url, range: Option<Range<usize>>) -> Result<Vec<u8>, anyhow::Error> {
fn get_webc_bytes(
url: &Url,
range: Option<Range<usize>>,
stream_response_into: Option<PathBuf>,
) -> Result<Option<Vec<u8>>, anyhow::Error> {
get_bytes(url, range, "application/webc", stream_response_into)
}
fn get_targz_bytes(
url: &Url,
range: Option<Range<usize>>,
stream_response_into: Option<PathBuf>,
) -> Result<Option<Vec<u8>>, anyhow::Error> {
get_bytes(url, range, "application/tar+gzip", stream_response_into)
}
fn get_bytes(
url: &Url,
range: Option<Range<usize>>,
application_type: &'static str,
stream_response_into: Option<PathBuf>,
) -> Result<Option<Vec<u8>>, anyhow::Error> {
// curl -r 0-500 -L https://wapm.dev/syrusakbary/python -H "Accept: application/webc" --output python.webc
let mut res = setup_webc_client(url)?;
let mut res = setup_client(url, application_type)?;
if let Some(range) = range.as_ref() {
res = res.header(RANGE, format!("bytes={}-{}", range.start, range.end));
}
let res = res
let mut res = res
.send()
.map_err(|e| anyhow::anyhow!("{e}"))
.context("send() failed")?;
if res.status().is_redirection() {
return Err(anyhow::anyhow!("redirect: {:?}", res.status()));
}
if res.status().is_server_error() {
return Err(anyhow::anyhow!("server error: {:?}", res.status()));
}
if res.status().is_client_error() {
return Err(anyhow::anyhow!("client error: {:?}", res.status()));
}
if let Some(path) = stream_response_into.as_ref() {
let mut file = std::fs::File::create(&path).map_err(|e| {
anyhow::anyhow!("failed to download {url} into {}: {e}", path.display())
})?;
res.copy_to(&mut file)
.map_err(|e| anyhow::anyhow!("{e}"))
.map_err(|e| {
anyhow::anyhow!("failed to download {url} into {}: {e}", path.display())
})?;
if application_type == "application/webc" {
let mut buf = vec![0; 100];
file.read_exact(&mut buf)
.map_err(|e| anyhow::anyhow!("invalid webc downloaded from {url}: {e}"))?;
if buf[0..webc::MAGIC.len()] != webc::MAGIC[..] {
let first_100_bytes = String::from_utf8_lossy(&buf);
return Err(anyhow::anyhow!("invalid webc bytes: {first_100_bytes:?}"));
}
}
Ok(None)
} else {
let bytes = res
.bytes()
.map_err(|e| anyhow::anyhow!("{e}"))
.context("bytes() failed")?;
Ok(bytes.to_vec())
if application_type == "application/webc"
&& (range.is_none() || range.unwrap().start == 0)
&& bytes[0..webc::MAGIC.len()] != webc::MAGIC[..]
{
let bytes = bytes.iter().copied().take(100).collect::<Vec<_>>();
let first_100_bytes = String::from_utf8_lossy(&bytes);
return Err(anyhow::anyhow!("invalid webc bytes: {first_100_bytes:?}"));
}
// else if "application/tar+gzip" - we would need to uncompress the response here
// since failure responses are very small, this will fail during unpacking instead
Ok(Some(bytes.to_vec()))
}
}
// TODO: this test is segfaulting only on linux-musl, no other OS
@@ -1235,39 +1009,25 @@ fn test_install_package() {
"https://registry-cdn.wapm.io/packages/wasmer/wabt/wabt-1.0.29.tar.gz".to_string()
);
let (package, _) = install_package(
TEST_NAME,
Some(registry),
"wasmer/wabt",
Some("1.0.29"),
None,
true,
)
.unwrap();
let path = install_package(TEST_NAME, &url::Url::parse(&wabt.url).unwrap()).unwrap();
println!("package installed: {package:#?}");
println!("package installed: {path:?}");
assert_eq!(
package.get_path(TEST_NAME).unwrap(),
get_global_install_dir(TEST_NAME, "registry.wapm.io")
path,
get_checkouts_dir(TEST_NAME)
.unwrap()
.join("wasmer")
.join("wabt")
.join("1.0.29")
.join(&format!("{}@1.0.29", Package::hash_url(&wabt.url)))
);
let all_installed_packages = get_all_local_packages(TEST_NAME, Some(registry));
println!("all_installed_packages: {all_installed_packages:#?}");
let all_installed_packages = get_all_local_packages(TEST_NAME);
let is_installed = all_installed_packages
.iter()
.any(|p| p.name == "wasmer/wabt" && p.version == "1.0.29");
println!("is_installed: {is_installed:#?}");
if !is_installed {
let panic_str = get_all_local_packages(TEST_NAME, Some(registry))
let panic_str = get_all_local_packages(TEST_NAME)
.iter()
.map(|p| format!("{} {} {}", p.registry, p.name, p.version))
.collect::<Vec<_>>()
@@ -1305,8 +1065,8 @@ pub struct BindingsGenerator {
pub command: String,
}
impl Display for BindingsGenerator {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
impl fmt::Display for BindingsGenerator {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let BindingsGenerator {
package_name,
version,

214
lib/registry/src/package.rs Normal file
View File

@@ -0,0 +1,214 @@
use crate::PartialWapmConfig;
use std::path::PathBuf;
use std::{fmt, str::FromStr};
use url::Url;
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Package {
pub namespace: String,
pub name: String,
pub version: Option<String>,
}
impl fmt::Display for Package {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.file())
}
}
impl Package {
/// Checks whether the package is already installed, if yes, returns the path to the root dir
pub fn already_installed(&self, #[cfg(test)] test_name: &str) -> Option<PathBuf> {
#[cfg(not(test))]
let checkouts_dir = crate::get_checkouts_dir()?;
#[cfg(test)]
let checkouts_dir = crate::get_checkouts_dir(test_name)?;
#[cfg(not(test))]
let hash = self.get_hash();
#[cfg(test)]
let hash = self.get_hash(test_name);
let found = std::fs::read_dir(&checkouts_dir)
.ok()?
.filter_map(|e| Some(e.ok()?.file_name().to_str()?.to_string()))
.find(|s| match self.version.as_ref() {
None => s.contains(&hash),
Some(v) => s.contains(&hash) && s.ends_with(v),
})?;
Some(checkouts_dir.join(found))
}
/// Checks if the URL is already installed, note that `{url}@{version}`
/// and `{url}` are treated the same
pub fn is_url_already_installed(url: &Url, #[cfg(test)] test_name: &str) -> Option<PathBuf> {
#[cfg(not(test))]
let checkouts_dir = crate::get_checkouts_dir()?;
#[cfg(test)]
let checkouts_dir = crate::get_checkouts_dir(test_name)?;
let url_string = url.to_string();
let (url, version) = match url_string.split('@').collect::<Vec<_>>()[..] {
[url, version] => (url.to_string(), Some(version)),
_ => (url_string, None),
};
let hash = Self::hash_url(&url);
let found = std::fs::read_dir(&checkouts_dir)
.ok()?
.filter_map(|e| Some(e.ok()?.file_name().to_str()?.to_string()))
.find(|s| match version.as_ref() {
None => s.contains(&hash),
Some(v) => s.contains(&hash) && s.ends_with(v),
})?;
Some(checkouts_dir.join(found))
}
/// Returns the hash of the URL with a maximum of 128 bytes length
/// (necessary for not erroring on filesystem limitations)
pub fn hash_url(url: &str) -> String {
hex::encode(url).chars().take(128).collect()
}
/// Returns the hash of the URL with a maximum of 64 bytes length
pub fn unhash_url(hashed: &str) -> String {
String::from_utf8_lossy(&hex::decode(hashed).unwrap_or_default()).to_string()
}
/// Returns the hash of the package URL without the version
/// (because the version is encoded as @version and isn't part of the hash itself)
pub fn get_hash(&self, #[cfg(test)] test_name: &str) -> String {
#[cfg(test)]
let url = self.get_url_without_version(test_name);
#[cfg(not(test))]
let url = self.get_url_without_version();
Self::hash_url(&url.unwrap_or_default())
}
fn get_url_without_version(
&self,
#[cfg(test)] test_name: &str,
) -> Result<String, anyhow::Error> {
#[cfg(test)]
let url = self.url(test_name);
#[cfg(not(test))]
let url = self.url();
Ok(format!(
"{}/{}/{}",
url?.origin().ascii_serialization(),
self.namespace,
self.name
))
}
/// Returns the filename for this package
pub fn file(&self) -> String {
let version = self
.version
.as_ref()
.map(|f| format!("@{f}"))
.unwrap_or_default();
format!("{}/{}{version}", self.namespace, self.name)
}
/// Returns the {namespace}/{name} package name
pub fn package(&self) -> String {
format!("{}/{}", self.namespace, self.name)
}
/// Returns the full URL including the version for this package
pub fn url(&self, #[cfg(test)] test_name: &str) -> Result<Url, anyhow::Error> {
#[cfg(test)]
let config = PartialWapmConfig::from_file(test_name)
.map_err(|e| anyhow::anyhow!("could not read wapm config: {e}"))?;
#[cfg(not(test))]
let config = PartialWapmConfig::from_file()
.map_err(|e| anyhow::anyhow!("could not read wapm config: {e}"))?;
let registry = config.registry.get_current_registry();
let registry_tld = tldextract::TldExtractor::new(tldextract::TldOption::default())
.extract(&registry)
.map_err(|e| anyhow::anyhow!("Invalid registry: {}: {e}", registry))?;
let registry_tld = format!(
"{}.{}",
registry_tld.domain.as_deref().unwrap_or(""),
registry_tld.suffix.as_deref().unwrap_or(""),
);
let version = self
.version
.as_ref()
.map(|f| format!("@{f}"))
.unwrap_or_default();
let url = format!(
"https://{registry_tld}/{}/{}{version}",
self.namespace, self.name
);
url::Url::parse(&url).map_err(|e| anyhow::anyhow!("error parsing {url}: {e}"))
}
/// Returns the path to the installation directory.
/// Does not check whether the installation directory already exists.
pub fn get_path(&self, #[cfg(test)] test_name: &str) -> Result<PathBuf, anyhow::Error> {
#[cfg(test)]
let checkouts_dir = crate::get_checkouts_dir(test_name);
#[cfg(not(test))]
let checkouts_dir = crate::get_checkouts_dir();
let checkouts_dir = checkouts_dir.ok_or_else(|| anyhow::anyhow!("no checkouts dir"))?;
#[cfg(not(test))]
let hash = self.get_hash();
#[cfg(test)]
let hash = self.get_hash(test_name);
match self.version.as_ref() {
Some(v) => Ok(checkouts_dir.join(format!("{}@{}", hash, v))),
None => Ok(checkouts_dir.join(&hash)),
}
}
}
impl FromStr for Package {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let regex =
regex::Regex::new(r#"^([a-zA-Z0-9\-_]+)/([a-zA-Z0-9\-_]+)(@([a-zA-Z0-9\.\-_]+*))?$"#)
.unwrap();
let captures = regex
.captures(s.trim())
.map(|c| {
c.iter()
.flatten()
.map(|m| m.as_str().to_owned())
.collect::<Vec<_>>()
})
.unwrap_or_default();
match captures.len() {
// namespace/package
3 => {
let namespace = captures[1].to_string();
let name = captures[2].to_string();
Ok(Package {
namespace,
name,
version: None,
})
}
// namespace/package@version
5 => {
let namespace = captures[1].to_string();
let name = captures[2].to_string();
let version = captures[4].to_string();
Ok(Package {
namespace,
name,
version: Some(version),
})
}
other => Err(anyhow::anyhow!("invalid package {other}")),
}
}
}

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-types"
version = "3.0.2"
version = "3.1.0"
description = "Wasmer Common Types"
categories = ["wasm", "no-std", "data-structures"]
keywords = ["wasm", "webassembly", "types"]

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-vbus"
version = "3.0.2"
version = "3.1.0"
description = "Wasmer Virtual Bus"
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
license = "MIT"
@@ -13,9 +13,9 @@ thiserror = "1"
tracing = { version = "0.1" }
typetag = { version = "0.1", optional = true }
slab = { version = "0.4", optional = true }
wasmer = { path = "../api", version = "=3.0.2", default-features = false }
wasmer-vfs = { path = "../vfs", version = "=3.0.2", default-features = false }
wasmer-wasi-types = { path = "../wasi-types/", version = "3.0.2" }
wasmer = { path = "../api", version = "=3.1.0", default-features = false }
wasmer-vfs = { path = "../vfs", version = "=3.1.0", default-features = false }
wasmer-wasi-types = { path = "../wasi-types/", version = "3.1.0" }
[features]
default = []

View File

@@ -1,14 +1,14 @@
[package]
name = "wasmer-vfs"
version = "3.0.2"
version = "3.1.0"
description = "Wasmer Virtual FileSystem"
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
license = "MIT"
edition = "2018"
[dependencies]
wasmer-types = { path = "../types", version = "3.0.2", default_features = false }
wasmer-wasi-types = { path = "../wasi-types", version = "3.0.2", default_features = false }
wasmer-types = { path = "../types", version = "3.1.0", default_features = false }
wasmer-wasi-types = { path = "../wasi-types", version = "3.1.0", default_features = false }
libc = { version = "^0.2", default-features = false, optional = true }
thiserror = "1"

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-vm"
version = "3.0.2"
version = "3.1.0"
description = "Runtime library support for Wasmer"
categories = ["wasm"]
keywords = ["wasm", "webassembly"]
@@ -11,7 +11,7 @@ readme = "README.md"
edition = "2018"
[dependencies]
wasmer-types = { path = "../types", version = "=3.0.2" }
wasmer-types = { path = "../types", version = "=3.1.0" }
libc = { version = "^0.2", default-features = false }
memoffset = "0.6"
indexmap = { version = "1.6" }

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-vnet"
version = "3.0.2"
version = "3.1.0"
description = "Wasmer Virtual Networking"
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
license = "MIT"
@@ -8,7 +8,7 @@ edition = "2018"
[dependencies]
thiserror = "1"
wasmer-vfs = { path = "../vfs", version = "=3.0.2", default-features = false }
wasmer-vfs = { path = "../vfs", version = "=3.1.0", default-features = false }
bytes = "1"
async-trait = { version = "^0.1" }

View File

@@ -18,7 +18,7 @@ once_cell = "1.13"
thiserror = "1.0"
tracing-lib = { version = "0.1.26", optional = true, package = "tracing" }
wai-bindgen-wasmer-impl = { version = "0.2.2" }
wasmer = { version = "3.0.2", path = "../api", default-features = false }
wasmer = { version = "3.1.0", path = "../api", default-features = false }
[features]
# Enables generated code to emit events via the `tracing` crate whenever wasm is

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-wasi-experimental-io-devices"
version = "3.0.2"
version = "3.1.0"
description = "An experimental non-standard WASI extension for graphics"
categories = ["wasm"]
keywords = ["wasm", "webassembly", "types"]
@@ -14,7 +14,7 @@ edition = "2018"
maintenance = { status = "experimental" }
[dependencies]
wasmer-wasi = { version = "=3.0.2", path = "../wasi", default-features=false }
wasmer-wasi = { version = "=3.1.0", path = "../wasi", default-features=false }
tracing = "0.1"
minifb = { version = "0.23", optional = true }
nix = "0.25.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-wasi-local-networking"
version = "3.0.2"
version = "3.1.0"
description = "An WASIX extension for local networking"
categories = ["wasm"]
keywords = ["wasm", "webassembly", "types"]
@@ -14,8 +14,8 @@ edition = "2018"
maintenance = { status = "experimental" }
[dependencies]
wasmer-vnet = { version = "=3.0.2", path = "../vnet", default-features = false }
wasmer-vfs = { path = "../vfs", version = "=3.0.2", default-features = false }
wasmer-vnet = { version = "=3.1.0", path = "../vnet", default-features = false }
wasmer-vfs = { path = "../vfs", version = "=3.1.0", default-features = false }
tracing = "0.1"
bytes = "1.1"
tokio = { version = "1", features = [ "sync", "macros", "io-util", "signal" ], default_features = false }

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-wasi-types"
version = "3.0.2"
version = "3.1.0"
description = "WASI types for Wasmer WebAssembly runtime"
categories = ["wasm", "os"]
keywords = ["wasm", "webassembly", "wasi", "sandbox", "ABI"]
@@ -14,8 +14,8 @@ edition = "2018"
[dependencies]
wasmer = { default-features = false, path = "../api", version = "3.0.0-beta" }
wasmer-types = { path = "../types", version = "=3.0.2" }
wasmer-derive = { path = "../derive", version = "=3.0.2" }
wasmer-types = { path = "../types", version = "=3.1.0" }
wasmer-derive = { path = "../derive", version = "=3.1.0" }
wai-bindgen-gen-rust = "0.2.1"
wai-bindgen-rust = { version = "0.2.1", default-features = false, features = ["macros"] }

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-wasi"
version = "3.0.2"
version = "3.1.0"
description = "WASI implementation library for Wasmer WebAssembly runtime"
categories = ["wasm", "os"]
keywords = ["wasm", "webassembly", "wasi", "sandbox", "ABI"]
@@ -16,13 +16,14 @@ thiserror = "1"
generational-arena = { version = "0.2" }
tracing = "0.1"
getrandom = "0.2"
wasmer-wasi-types = { path = "../wasi-types", version = "=3.0.2" }
wasmer-types = { path = "../types", version = "=3.0.2", default-features = false }
wasmer = { path = "../api", version = "=3.0.2", default-features = false, features = ["wat", "js-serializable-module"] }
wasmer-vfs = { path = "../vfs", version = "=3.0.2", default-features = false, features = ["webc-fs"] }
wasmer-vbus = { path = "../vbus", version = "=3.0.2", default-features = false }
wasmer-vnet = { path = "../vnet", version = "=3.0.2", default-features = false }
wasmer-wasi-local-networking = { path = "../wasi-local-networking", version = "=3.0.2", default-features = false, optional = true }
wasmer-wasi-types = { path = "../wasi-types", version = "=3.1.0" }
wasmer-types = { path = "../types", version = "=3.1.0", default-features = false }
wasmer = { path = "../api", version = "=3.1.0", default-features = false, features = ["wat", "js-serializable-module"] }
wasmer-vfs = { path = "../vfs", version = "=3.1.0", default-features = false, features = ["webc-fs"] }
wasmer-vbus = { path = "../vbus", version = "=3.1.0", default-features = false }
wasmer-vnet = { path = "../vnet", version = "=3.1.0", default-features = false }
wasmer-wasi-local-networking = { path = "../wasi-local-networking", version = "=3.1.0", default-features = false, optional = true }
wasmer-emscripten = { path = "../emscripten", version = "=3.1.0", optional = true }
typetag = { version = "0.1", optional = true }
serde = { version = "1.0", default-features = false, features = ["derive"] }
bincode = { version = "1.3", optional = true }
@@ -32,7 +33,6 @@ bytes = "1"
webc = { version = "3.0.1", default-features = false, features = ["std", "mmap"] }
serde_cbor = { version = "0.11.2", optional = true }
anyhow = { version = "1.0.66" }
wasmer-emscripten = { path = "../emscripten", version = "=3.0.2", optional = true }
lazy_static = "1.4"
sha2 = { version = "0.10" }
waker-fn = { version = "1.1" }

View File

@@ -63,7 +63,7 @@ def make_release(version):
raise Exception("could not clone github repo")
# generate changelog
proc = subprocess.Popen(['gh', "search", "prs", "--repo", "wasmerio/wasmer", "--merged", "--limit", "100"], stdout = subprocess.PIPE, cwd = temp_dir.name)
proc = subprocess.Popen(['gh', "search", "prs", "--repo", "wasmerio/wasmer", "--merged", "--limit", "100", "--sort", "updated"], stdout = subprocess.PIPE, cwd = temp_dir.name)
proc.wait()
if proc.returncode != 0:
print(proc.stdout)
@@ -120,7 +120,7 @@ def make_release(version):
for l in changelog:
print(" " + l)
proc = subprocess.Popen(['gh','search', "prs", "--repo", "wasmerio/wasmer", "--merged"], stdout = subprocess.PIPE, cwd = temp_dir.name)
proc = subprocess.Popen(['gh','search', "prs", "--repo", "wasmerio/wasmer", "--merged", "--sort", "updated"], stdout = subprocess.PIPE, cwd = temp_dir.name)
proc.wait()
already_released_str = ""
@@ -170,7 +170,7 @@ def make_release(version):
print(line.rstrip())
raise Exception("could not run git checkout -b release-" + RELEASE_VERSION)
replace(temp_dir.name + "/CHANGELOG.md", "## **Unreleased**", "\r\n".join(changelog))
replace(temp_dir.name + "/CHANGELOG.md", "## **Unreleased**", "\n".join(changelog))
proc = subprocess.Popen(['git','commit', "-am", "Update CHANGELOG"], stdout = subprocess.PIPE, cwd = temp_dir.name)
proc.wait()
@@ -338,7 +338,7 @@ def make_release(version):
print(line.rstrip())
raise Exception("could not pull origin ")
proc = subprocess.Popen(['gh','search', "prs", "--repo", "wasmerio/wasmer", "--merged"], stdout = subprocess.PIPE, cwd = temp_dir.name)
proc = subprocess.Popen(['gh','search', "prs", "--repo", "wasmerio/wasmer", "--merged", "--sort", "updated"], stdout = subprocess.PIPE, cwd = temp_dir.name)
proc.wait()
github_link_line = ""

View File

@@ -1,7 +1,7 @@
#!/usr/bin/python
PREVIOUS_VERSION='3.0.1'
NEXT_VERSION='3.0.2'
PREVIOUS_VERSION='3.0.2'
NEXT_VERSION='3.1.0'
import os
import re

View File

@@ -1,6 +1,6 @@
[Setup]
AppName=Wasmer
AppVersion=3.0.2
AppVersion=3.1.0
DefaultDirName={pf}\Wasmer
DefaultGroupName=Wasmer
Compression=lzma2

View File

@@ -317,3 +317,108 @@ fn test_popcnt(mut config: crate::Config) -> Result<()> {
Ok(())
}
/// Create a large number of local (more than 0x1_0000 bytes, thats 32*16 i64 + 1)
/// to trigger an issue in the arm64 singlepass compiler
/// sequence
/// mov x17, #0x1010
/// sub xsp, xsp, x17
/// will tranform to
/// mov x17, #0x1010
/// sub xzr, xzr, x17
/// and the locals
/// on stack can get corrupted by subsequent calls if they also have locals on stack
#[compiler_test(issues)]
fn large_number_local(mut config: crate::Config) -> Result<()> {
let mut store = config.store();
let wat = r#"
(module
(func (;0;)
(local i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64)
i64.const 0
i64.const 5555
i64.add
local.set 8
i64.const 0
i64.const 5555
i64.add
local.set 9
i64.const 0
i64.const 5555
i64.add
local.set 10
)
(func $large_local (export "large_local") (result i64)
(local
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64
i64
)
(local.set 15 (i64.const 1))
(call 0)
local.get 6
local.get 7
i64.add
local.get 8
i64.add
local.get 9
i64.add
local.get 10
i64.add
local.get 11
i64.add
local.get 12
i64.add
local.get 13
i64.add
local.get 14
i64.add
local.get 15
i64.add
local.get 16
i64.add
)
)
"#;
let mut env = FunctionEnv::new(&mut store, ());
let module = Module::new(&store, wat)?;
let imports: Imports = imports! {};
let instance = Instance::new(&mut store, &module, &imports)?;
let result = instance
.exports
.get_function("large_local")?
.call(&mut store, &[])
.unwrap();
assert_eq!(&Value::I64(1 as i64), result.get(0).unwrap());
Ok(())
}

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-integration-tests-cli"
version = "3.0.2"
version = "3.1.0"
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
description = "CLI integration tests"
repository = "https://github.com/wasmerio/wasmer"

View File

@@ -21,7 +21,6 @@ fn test_no_start_wat_path() -> PathBuf {
Path::new(ASSET_PATH).join("no_start.wat")
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
#[test]
fn test_cross_compile_python_windows() -> anyhow::Result<()> {
let temp_dir = tempfile::TempDir::new()?;
@@ -34,7 +33,28 @@ fn test_cross_compile_python_windows() -> anyhow::Result<()> {
"x86_64-windows-gnu",
];
// MUSL has no support for LLVM in C-API
#[cfg(target_env = "musl")]
let compilers = &["cranelift", "singlepass"];
#[cfg(not(target_env = "musl"))]
let compilers = &["cranelift", "singlepass", "llvm"];
// llvm-objdump --disassemble-all --demangle ./objects/wasmer_vm-50cb118b098c15db.wasmer_vm.60425a0a-cgu.12.rcgu.o
// llvm-objdump --macho --exports-trie ~/.wasmer/cache/wasmer-darwin-arm64/lib/libwasmer.dylib
let excluded_combinations = &[
("aarch64-darwin", "llvm"), // LLVM: aarch64 not supported relocation Arm64MovwG0 not supported
("aarch64-linux-gnu", "llvm"), // LLVM: aarch64 not supported relocation Arm64MovwG0 not supported
// https://github.com/ziglang/zig/issues/13729
("x86_64-darwin", "llvm"), // undefined reference to symbol 'wasmer_vm_raise_trap' kind Unknown
("x86_64-windows-gnu", "llvm"), // unimplemented symbol `wasmer_vm_raise_trap` kind Unknown
];
for t in targets {
for c in compilers {
if excluded_combinations.contains(&(t, c)) {
continue;
}
println!("{t} target {c}");
let python_wasmer_path = temp_dir.path().join(format!("{t}-python"));
let mut output = Command::new(get_wasmer_path());
@@ -45,6 +65,13 @@ fn test_cross_compile_python_windows() -> anyhow::Result<()> {
output.arg(t);
output.arg("-o");
output.arg(python_wasmer_path.clone());
output.arg(format!("--{c}"));
if t.contains("x86_64") && *c == "singlepass" {
output.arg("-m");
output.arg("avx");
}
let output = output.output()?;
let stdout = std::str::from_utf8(&output.stdout)
@@ -71,6 +98,7 @@ fn test_cross_compile_python_windows() -> anyhow::Result<()> {
);
}
}
}
Ok(())
}
@@ -380,7 +408,7 @@ fn test_wasmer_run_works_with_dir() -> anyhow::Result<()> {
#[test]
fn test_wasmer_run_works() -> anyhow::Result<()> {
let output = Command::new(get_wasmer_path())
.arg("registry.wapm.io/python/python")
.arg("https://wapm.io/python/python")
.arg(format!("--mapdir=.:{}", ASSET_PATH))
.arg("test.py")
.output()?;
@@ -400,7 +428,7 @@ fn test_wasmer_run_works() -> anyhow::Result<()> {
// same test again, but this time with "wasmer run ..."
let output = Command::new(get_wasmer_path())
.arg("run")
.arg("registry.wapm.io/python/python")
.arg("https://wapm.io/python/python")
.arg(format!("--mapdir=.:{}", ASSET_PATH))
.arg("test.py")
.output()?;
@@ -417,6 +445,15 @@ fn test_wasmer_run_works() -> anyhow::Result<()> {
);
}
// set wapm.io as the current registry
let _ = Command::new(get_wasmer_path())
.arg("login")
.arg("--registry")
.arg("wapm.io")
// will fail, but set wapm.io as the current registry regardless
.arg("öladkfjasöldfkjasdölfkj")
.output()?;
// same test again, but this time without specifying the registry
let output = Command::new(get_wasmer_path())
.arg("run")
@@ -440,7 +477,7 @@ fn test_wasmer_run_works() -> anyhow::Result<()> {
// same test again, but this time with only the command "python" (should be looked up locally)
let output = Command::new(get_wasmer_path())
.arg("run")
.arg("python")
.arg("_/python")
.arg(format!("--mapdir=.:{}", ASSET_PATH))
.arg("test.py")
.output()?;
@@ -480,6 +517,133 @@ fn run_no_imports_wasm_works() -> anyhow::Result<()> {
Ok(())
}
#[test]
fn run_wasi_works_non_existent() -> anyhow::Result<()> {
let output = Command::new(get_wasmer_path())
.arg("run")
.arg("does/not/exist")
.output()?;
let stderr = std::str::from_utf8(&output.stderr).unwrap();
let stderr_lines = stderr.lines().map(|s| s.to_string()).collect::<Vec<_>>();
assert_eq!(
stderr_lines,
vec!["error: invalid package name, could not find file does/not/exist".to_string()]
);
Ok(())
}
#[test]
fn run_test_caching_works_for_packages() -> anyhow::Result<()> {
// set wapm.io as the current registry
let _ = Command::new(get_wasmer_path())
.arg("login")
.arg("--registry")
.arg("wapm.io")
// will fail, but set wapm.io as the current registry regardless
.arg("öladkfjasöldfkjasdölfkj")
.output()?;
let output = Command::new(get_wasmer_path())
.arg("python/python")
.arg(format!("--mapdir=.:{}", ASSET_PATH))
.arg("test.py")
.output()?;
if output.stdout != b"hello\n".to_vec() {
panic!("failed to run https://wapm.io/python/python for the first time");
}
let time = std::time::Instant::now();
let output = Command::new(get_wasmer_path())
.arg("python/python")
.arg(format!("--mapdir=.:{}", ASSET_PATH))
.arg("test.py")
.output()?;
if output.stdout != b"hello\n".to_vec() {
panic!("failed to run https://wapm.io/python/python for the second time");
}
// package should be cached
assert!(std::time::Instant::now() - time < std::time::Duration::from_secs(1));
Ok(())
}
#[test]
fn run_test_caching_works_for_packages_with_versions() -> anyhow::Result<()> {
// set wapm.io as the current registry
let _ = Command::new(get_wasmer_path())
.arg("login")
.arg("--registry")
.arg("wapm.io")
// will fail, but set wapm.io as the current registry regardless
.arg("öladkfjasöldfkjasdölfkj")
.output()?;
let output = Command::new(get_wasmer_path())
.arg("python/python@0.1.0")
.arg(format!("--mapdir=.:{}", ASSET_PATH))
.arg("test.py")
.output()?;
if output.stdout != b"hello\n".to_vec() {
panic!("failed to run https://wapm.io/python/python for the first time");
}
let time = std::time::Instant::now();
let output = Command::new(get_wasmer_path())
.arg("python/python@0.1.0")
.arg(format!("--mapdir=.:{}", ASSET_PATH))
.arg("test.py")
.output()?;
if output.stdout != b"hello\n".to_vec() {
panic!("failed to run https://wapm.io/python/python for the second time");
}
// package should be cached
assert!(std::time::Instant::now() - time < std::time::Duration::from_secs(1));
Ok(())
}
#[test]
fn run_test_caching_works_for_urls() -> anyhow::Result<()> {
let output = Command::new(get_wasmer_path())
.arg("https://wapm.io/python/python")
.arg(format!("--mapdir=.:{}", ASSET_PATH))
.arg("test.py")
.output()?;
if output.stdout != b"hello\n".to_vec() {
panic!("failed to run https://wapm.io/python/python for the first time");
}
let time = std::time::Instant::now();
let output = Command::new(get_wasmer_path())
.arg("https://wapm.io/python/python")
.arg(format!("--mapdir=.:{}", ASSET_PATH))
.arg("test.py")
.output()?;
if output.stdout != b"hello\n".to_vec() {
panic!("failed to run https://wapm.io/python/python for the second time");
}
// package should be cached
assert!(std::time::Instant::now() - time < std::time::Duration::from_secs(1));
Ok(())
}
// This test verifies that "wasmer run --invoke _start module.wat"
// works the same as "wasmer run module.wat" (without --invoke).
#[test]

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-integration-tests-ios"
version = "3.0.2"
version = "3.1.0"
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
description = "iOS integration tests"
repository = "https://github.com/wasmerio/wasmer"

View File

@@ -1,6 +1,6 @@
[package]
name = "wasmer-wast"
version = "3.0.2"
version = "3.1.0"
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
description = "wast testing support for wasmer"
license = "MIT OR Apache-2.0 WITH LLVM-exception"
@@ -12,9 +12,9 @@ edition = "2018"
[dependencies]
anyhow = "1.0"
wasmer = { path = "../../../lib/api", version = "=3.0.2", default-features = false }
wasmer-wasi = { path = "../../../lib/wasi", version = "=3.0.2" }
wasmer-vfs = { path = "../../../lib/vfs", version = "=3.0.2" }
wasmer = { path = "../../../lib/api", version = "=3.1.0", default-features = false }
wasmer-wasi = { path = "../../../lib/wasi", version = "=3.1.0" }
wasmer-vfs = { path = "../../../lib/vfs", version = "=3.1.0" }
wast = "38.0"
serde = "1"
tempfile = "3"

View File

@@ -1,6 +1,6 @@
[package]
name = "wasi-test-generator"
version = "3.0.2"
version = "3.1.0"
description = "Tests for our WASI implementation"
license = "MIT"
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]