|
|
|
[package]
|
|
|
|
name = "wasmtime-cli"
|
|
|
|
version.workspace = true
|
|
|
|
authors.workspace = true
|
|
|
|
description = "Command-line interface for Wasmtime"
|
|
|
|
license = "Apache-2.0 WITH LLVM-exception"
|
|
|
|
documentation = "https://bytecodealliance.github.io/wasmtime/cli.html"
|
|
|
|
categories = ["wasm"]
|
|
|
|
keywords = ["webassembly", "wasm"]
|
|
|
|
repository = "https://github.com/bytecodealliance/wasmtime"
|
|
|
|
readme = "README.md"
|
|
|
|
edition.workspace = true
|
|
|
|
default-run = "wasmtime"
|
|
|
|
|
|
|
|
[lib]
|
|
|
|
doctest = false
|
|
|
|
|
|
|
|
[[bin]]
|
|
|
|
name = "wasmtime"
|
|
|
|
path = "src/bin/wasmtime.rs"
|
|
|
|
doc = false
|
|
|
|
|
|
|
|
[dependencies]
|
|
|
|
wasmtime = { workspace = true, features = ['cache', 'cranelift'] }
|
|
|
|
wasmtime-cache = { workspace = true }
|
|
|
|
wasmtime-cli-flags = { workspace = true }
|
|
|
|
wasmtime-cranelift = { workspace = true }
|
|
|
|
wasmtime-environ = { workspace = true }
|
|
|
|
wasmtime-wast = { workspace = true }
|
|
|
|
wasmtime-wasi = { workspace = true }
|
|
|
|
wasmtime-wasi-crypto = { workspace = true, optional = true }
|
|
|
|
wasmtime-wasi-nn = { workspace = true, optional = true }
|
|
|
|
clap = { workspace = true, features = ["color", "suggestions", "derive"] }
|
|
|
|
anyhow = { workspace = true }
|
|
|
|
target-lexicon = { workspace = true }
|
|
|
|
libc = "0.2.60"
|
|
|
|
humantime = "2.0.0"
|
|
|
|
once_cell = { workspace = true }
|
|
|
|
listenfd = "1.0.0"
|
|
|
|
|
|
|
|
[target.'cfg(unix)'.dependencies]
|
|
|
|
rustix = { workspace = true, features = ["mm", "param"] }
|
|
|
|
|
|
|
|
[dev-dependencies]
|
Refactor fuzzing configuration and sometimes disable debug verifier. (#3664)
* fuzz: Refactor Wasmtime's fuzz targets
A recent fuzz bug found is related to timing out when compiling a
module. This timeout, however, is predominately because Cranelift's
debug verifier is enabled and taking up over half the compilation time.
I wanted to fix this by disabling the verifier when input modules might
have a lot of functions, but this was pretty difficult to implement.
Over time we've grown a number of various fuzzers. Most are
`wasm-smith`-based at this point but there's various entry points for
configuring the wasm-smith module, the wasmtime configuration, etc. I've
historically gotten quite lost in trying to change defaults and feeling
like I have to touch a lot of different places. This is the motivation
for this commit, simplifying fuzzer default configuration.
This commit removes the ability to create a default `Config` for
fuzzing, instead only supporting generating a configuration via
`Arbitrary`. This then involved refactoring all targets and fuzzers to
ensure that configuration is generated through `Arbitrary`. This should
actually expand the coverage of some existing fuzz targets since
`Arbitrary for Config` will tweak options that don't affect runtime,
such as memory configuration or jump veneers.
All existing fuzz targets are refactored to use this new method of
configuration. Some fuzz targets were also shuffled around or
reimplemented:
* `compile` - this now directly calls `Module::new` to skip all the
fuzzing infrastructure. This is mostly done because this fuzz target
isn't too interesting and is largely just seeing what happens when
things are thrown at the wall for Wasmtime.
* `instantiate-maybe-invalid` - this fuzz target now skips instantiation
and instead simply goes into `Module::new` like the `compile` target.
The rationale behind this is that most modules won't instantiate
anyway and this fuzz target is primarily fuzzing the compiler. This
skips having to generate arbitrary configuration since
wasm-smith-generated-modules (or valid ones at least) aren't used
here.
* `instantiate` - this fuzz target was removed. In general this fuzz
target isn't too interesting in isolation. Almost everything it deals
with likely won't pass compilation and is covered by the `compile`
fuzz target, and otherwise interesting modules being instantiated can
all theoretically be created by `wasm-smith` anyway.
* `instantiate-wasm-smith` and `instantiate-swarm` - these were both merged
into a new `instantiate` target (replacing the old one from above).
There wasn't really much need to keep these separate since they really
only differed at this point in methods of timeout. Otherwise we much
more heavily use `SwarmConfig` than wasm-smith's built-in options.
The intention is that we should still have basically the same coverage
of fuzzing as before, if not better because configuration is now
possible on some targets. Additionally there is one centralized point of
configuration for fuzzing for wasmtime, `Arbitrary for ModuleConfig`.
This internally creates an arbitrary `SwarmConfig` from `wasm-smith` and
then further tweaks it for Wasmtime's needs, such as enabling various
wasm proposals by default. In the future enabling a wasm proposal on
fuzzing should largely just be modifying this one trait implementation.
* fuzz: Sometimes disable the cranelift debug verifier
This commit disables the cranelift debug verifier if the input wasm
module might be "large" for the definition of "more than 10 functions".
While fuzzing we disable threads (set them to 1) and enable the
cranelift debug verifier. Coupled with a 20-30x slowdown this means that
a module with the maximum number of functions, 100, gives:
60x / 100 functions / 30x slowdown = 20ms
With only 20 milliseconds per function this is even further halved by
the `differential` fuzz target compiling a module twice, which means
that, when compiling with a normal release mode Wasmtime, if any
function takes more than 10ms to compile then it's a candidate for
timing out while fuzzing. Given that the cranelift debug verifier can
more than double compilation time in fuzzing mode this actually means
that the real time budget for function compilation is more like 4ms.
The `wasm-smith` crate can pretty easily generate a large function that
takes 4ms to compile, and then when that function is multiplied 100x in
the `differential` fuzz target we trivially time out the fuzz target.
The hope of this commit is to buy back half our budget by disabling the
debug verifier for modules that may have many functions. Further
refinements can be implemented in the future such as limiting functions
for just the differential target as well.
* Fix the single-function-module fuzz configuration
* Tweak how features work in differential fuzzing
* Disable everything for baseline differential fuzzing
* Enable selectively for each engine afterwards
* Also forcibly enable reference types and bulk memory for spec tests
* Log wasms when compiling
* Add reference types support to v8 fuzzer
* Fix timeouts via fuel
The default store has "infinite" fuel so that needs to be consumed
before fuel is added back in.
* Remove fuzzing-specific tests
These no longer compile and also haven't been added to in a long time.
Most of the time a reduced form of original the fuzz test case is added
when a fuzz bug is fixed.
3 years ago
|
|
|
# depend again on wasmtime to activate its default features for tests
|
|
|
|
wasmtime = { workspace = true, features = ['component-model', 'async', 'default'] }
|
|
|
|
env_logger = { workspace = true }
|
|
|
|
log = { workspace = true }
|
|
|
|
filecheck = "0.5.0"
|
|
|
|
tempfile = "3.1.0"
|
|
|
|
test-programs = { path = "crates/test-programs" }
|
|
|
|
wasmtime-runtime = { workspace = true }
|
|
|
|
tokio = { version = "1.8.0", features = ["rt", "time", "macros", "rt-multi-thread"] }
|
|
|
|
wast = { workspace = true }
|
|
|
|
criterion = "0.3.4"
|
|
|
|
num_cpus = "1.13.0"
|
Use an mmap-friendly serialization format (#3257)
* Use an mmap-friendly serialization format
This commit reimplements the main serialization format for Wasmtime's
precompiled artifacts. Previously they were generally a binary blob of
`bincode`-encoded metadata prefixed with some versioning information.
The downside of this format, though, is that loading a precompiled
artifact required pushing all information through `bincode`. This is
inefficient when some data, such as trap/address tables, are rarely
accessed.
The new format added in this commit is one which is designed to be
`mmap`-friendly. This means that the relevant parts of the precompiled
artifact are already page-aligned for updating permissions of pieces
here and there. Additionally the artifact is optimized so that if data
is rarely read then we can delay reading it until necessary.
The new artifact format for serialized modules is an ELF file. This is
not a public API guarantee, so it cannot be relied upon. In the meantime
though this is quite useful for exploring precompiled modules with
standard tooling like `objdump`. The ELF file is already constructed as
part of module compilation, and this is the main contents of the
serialized artifact.
THere is some extra information, though, not encoded in each module's
individual ELF file such as type information. This information continues
to be `bincode`-encoded, but it's intended to be much smaller and much
faster to deserialize. This extra information is appended to the end of
the ELF file. This means that the original ELF file is still a valid ELF
file, we just get to have extra bits at the end. More information on the
new format can be found in the module docs of the serialization module
of Wasmtime.
Another refatoring implemented as part of this commit is to deserialize
and store object files directly in `mmap`-backed storage. This avoids
the need to copy bytes after the artifact is loaded into memory for each
compiled module, and in a future commit it opens up the door to avoiding
copying the text section into a `CodeMemory`. For now, though, the main
change is that copies are not necessary when loading from a precompiled
compilation artifact once the artifact is itself in mmap-based memory.
To assist with managing `mmap`-based memory a new `MmapVec` type was
added to `wasmtime_jit` which acts as a form of `Vec<T>` backed by a
`wasmtime_runtime::Mmap`. This type notably supports `drain(..N)` to
slice the buffer into disjoint regions that are all separately owned,
such as having a separately owned window into one artifact for all
object files contained within.
Finally this commit implements a small refactoring in `wasmtime-cache`
to use the standard artifact format for cache entries rather than a
bincode-encoded version. This required some more hooks for
serializing/deserializing but otherwise the crate still performs as
before.
* Review comments
3 years ago
|
|
|
memchr = "2.4"
|
|
|
|
async-trait = "0.1"
|
|
|
|
wat = { workspace = true }
|
|
|
|
rayon = "1.5.0"
|
|
|
|
wasmtime-wast = { workspace = true, features = ['component-model'] }
|
|
|
|
wasmtime-component-util = { workspace = true }
|
|
|
|
component-macro-test = { path = "crates/misc/component-macro-test" }
|
|
|
|
component-test-util = { workspace = true }
|
|
|
|
|
|
|
|
[target.'cfg(windows)'.dev-dependencies]
|
|
|
|
windows-sys = { workspace = true, features = ["Win32_System_Memory"] }
|
|
|
|
|
|
|
|
[build-dependencies]
|
|
|
|
anyhow = { workspace = true }
|
|
|
|
|
|
|
|
[profile.release.build-override]
|
|
|
|
opt-level = 0
|
|
|
|
|
|
|
|
[workspace]
|
|
|
|
resolver = '2'
|
|
|
|
members = [
|
|
|
|
"cranelift",
|
|
|
|
"cranelift/egraph",
|
|
|
|
"cranelift/isle/fuzz",
|
|
|
|
"cranelift/isle/islec",
|
|
|
|
"cranelift/serde",
|
|
|
|
"crates/bench-api",
|
|
|
|
"crates/c-api",
|
|
|
|
"crates/cli-flags",
|
|
|
|
"crates/environ/fuzz",
|
|
|
|
"crates/jit-icache-coherence",
|
|
|
|
"examples/fib-debug/wasm",
|
|
|
|
"examples/wasi/wasm",
|
|
|
|
"examples/tokio/wasm",
|
|
|
|
"fuzz",
|
|
|
|
]
|
|
|
|
exclude = [
|
|
|
|
'crates/wasi-common/WASI/tools/witx-cli',
|
|
|
|
'docs/rust_wasi_markdown_parser'
|
|
|
|
]
|
|
|
|
|
|
|
|
[workspace.package]
|
|
|
|
version = "3.0.0"
|
|
|
|
authors = ["The Wasmtime Project Developers"]
|
|
|
|
edition = "2021"
|
|
|
|
|
|
|
|
[workspace.dependencies]
|
|
|
|
wasmtime = { path = "crates/wasmtime", version = "3.0.0", default-features = false }
|
|
|
|
wasmtime-cache = { path = "crates/cache", version = "=3.0.0" }
|
|
|
|
wasmtime-cli-flags = { path = "crates/cli-flags", version = "=3.0.0" }
|
|
|
|
wasmtime-cranelift = { path = "crates/cranelift", version = "=3.0.0" }
|
|
|
|
wasmtime-environ = { path = "crates/environ", version = "=3.0.0" }
|
|
|
|
wasmtime-fiber = { path = "crates/fiber", version = "=3.0.0" }
|
|
|
|
wasmtime-types = { path = "crates/types", version = "3.0.0" }
|
|
|
|
wasmtime-jit = { path = "crates/jit", version = "=3.0.0" }
|
|
|
|
wasmtime-jit-debug = { path = "crates/jit-debug", version = "=3.0.0" }
|
|
|
|
wasmtime-runtime = { path = "crates/runtime", version = "=3.0.0" }
|
|
|
|
wasmtime-wast = { path = "crates/wast", version = "=3.0.0" }
|
|
|
|
wasmtime-wasi = { path = "crates/wasi", version = "3.0.0" }
|
|
|
|
wasmtime-wasi-crypto = { path = "crates/wasi-crypto", version = "3.0.0" }
|
|
|
|
wasmtime-wasi-nn = { path = "crates/wasi-nn", version = "3.0.0" }
|
|
|
|
wasmtime-component-util = { path = "crates/component-util", version = "=3.0.0" }
|
|
|
|
wasmtime-component-macro = { path = "crates/component-macro", version = "=3.0.0" }
|
|
|
|
wasmtime-asm-macros = { path = "crates/asm-macros", version = "=3.0.0" }
|
|
|
|
component-test-util = { path = "crates/misc/component-test-util" }
|
|
|
|
component-fuzz-util = { path = "crates/misc/component-fuzz-util" }
|
|
|
|
wiggle = { path = "crates/wiggle", version = "=3.0.0", default-features = false }
|
|
|
|
wiggle-macro = { path = "crates/wiggle/macro", version = "=3.0.0" }
|
|
|
|
wiggle-generate = { path = "crates/wiggle/generate", version = "=3.0.0" }
|
|
|
|
wasi-common = { path = "crates/wasi-common", version = "=3.0.0" }
|
|
|
|
wasi-tokio = { path = "crates/wasi-common/tokio", version = "=3.0.0" }
|
|
|
|
wasi-cap-std-sync = { path = "crates/wasi-common/cap-std-sync", version = "=3.0.0" }
|
|
|
|
wasmtime-fuzzing = { path = "crates/fuzzing" }
|
|
|
|
wasmtime-jit-icache-coherence = { path = "crates/jit-icache-coherence", version = "=2.0.0" }
|
|
|
|
|
|
|
|
cranelift-wasm = { path = "cranelift/wasm", version = "0.90.0" }
|
|
|
|
cranelift-codegen = { path = "cranelift/codegen", version = "0.90.0" }
|
|
|
|
cranelift-egraph = { path = "cranelift/egraph", version = "0.90.0" }
|
|
|
|
cranelift-frontend = { path = "cranelift/frontend", version = "0.90.0" }
|
|
|
|
cranelift-entity = { path = "cranelift/entity", version = "0.90.0" }
|
|
|
|
cranelift-native = { path = "cranelift/native", version = "0.90.0" }
|
|
|
|
cranelift-module = { path = "cranelift/module", version = "0.90.0" }
|
|
|
|
cranelift-interpreter = { path = "cranelift/interpreter", version = "0.90.0" }
|
|
|
|
cranelift-reader = { path = "cranelift/reader", version = "0.90.0" }
|
|
|
|
cranelift-filetests = { path = "cranelift/filetests" }
|
|
|
|
cranelift-object = { path = "cranelift/object", version = "0.90.0" }
|
|
|
|
cranelift-jit = { path = "cranelift/jit", version = "0.90.0" }
|
|
|
|
cranelift-preopt = { path = "cranelift/preopt", version = "0.90.0" }
|
|
|
|
cranelift-fuzzgen = { path = "cranelift/fuzzgen" }
|
|
|
|
cranelift-bforest = { path = "cranelift/bforest", version = "0.90.0" }
|
|
|
|
cranelift = { path = "cranelift/umbrella", version = "0.90.0" }
|
|
|
|
|
|
|
|
target-lexicon = { version = "0.12.3", default-features = false }
|
|
|
|
anyhow = "1.0.22"
|
|
|
|
wasmparser = "0.92.0"
|
|
|
|
wat = "1.0.49"
|
|
|
|
wast = "47.0.1"
|
|
|
|
wasmprinter = "0.2.41"
|
|
|
|
wasm-encoder = "0.18.0"
|
|
|
|
wasm-smith = "0.11.6"
|
|
|
|
wasm-mutate = "0.2.9"
|
|
|
|
windows-sys = "0.36.0"
|
|
|
|
env_logger = "0.9"
|
|
|
|
rustix = "0.35.10"
|
|
|
|
log = { version = "0.4.8", default-features = false }
|
|
|
|
object = { version = "0.29", default-features = false, features = ['read_core', 'elf', 'std'] }
|
|
|
|
gimli = { version = "0.26.0", default-features = false, features = ['read', 'std'] }
|
|
|
|
clap = { version = "3.2.0", features = ["color", "suggestions", "derive"] }
|
|
|
|
hashbrown = "0.12"
|
|
|
|
cap-std = "0.26.0"
|
|
|
|
once_cell = "1.12.0"
|
|
|
|
smallvec = { version = "1.6.1", features = ["union"] }
|
|
|
|
|
|
|
|
[features]
|
|
|
|
default = [
|
|
|
|
"jitdump",
|
|
|
|
"wasmtime/wat",
|
|
|
|
"wasmtime/parallel-compilation",
|
|
|
|
"vtune",
|
|
|
|
"wasi-nn",
|
|
|
|
"pooling-allocator",
|
|
|
|
"memory-init-cow",
|
|
|
|
]
|
|
|
|
jitdump = ["wasmtime/jitdump"]
|
|
|
|
vtune = ["wasmtime/vtune"]
|
|
|
|
wasi-crypto = ["dep:wasmtime-wasi-crypto"]
|
|
|
|
wasi-nn = ["dep:wasmtime-wasi-nn"]
|
|
|
|
memory-init-cow = ["wasmtime/memory-init-cow", "wasmtime-cli-flags/memory-init-cow"]
|
|
|
|
pooling-allocator = ["wasmtime/pooling-allocator", "wasmtime-cli-flags/pooling-allocator"]
|
|
|
|
all-arch = ["wasmtime/all-arch"]
|
|
|
|
posix-signals-on-macos = ["wasmtime/posix-signals-on-macos"]
|
|
|
|
component-model = [
|
|
|
|
"wasmtime/component-model",
|
|
|
|
"wasmtime-wast/component-model",
|
|
|
|
"wasmtime-cli-flags/component-model"
|
|
|
|
]
|
|
|
|
|
|
|
|
# Stub feature that does nothing, for Cargo-features compatibility: the new
|
|
|
|
# backend is the default now.
|
|
|
|
experimental_x64 = []
|
|
|
|
|
|
|
|
[badges]
|
|
|
|
maintenance = { status = "actively-developed" }
|
|
|
|
|
|
|
|
[[test]]
|
|
|
|
name = "host_segfault"
|
|
|
|
harness = false
|
externref: implement stack map-based garbage collection
For host VM code, we use plain reference counting, where cloning increments
the reference count, and dropping decrements it. We can avoid many of the
on-stack increment/decrement operations that typically plague the
performance of reference counting via Rust's ownership and borrowing system.
Moving a `VMExternRef` avoids mutating its reference count, and borrowing it
either avoids the reference count increment or delays it until if/when the
`VMExternRef` is cloned.
When passing a `VMExternRef` into compiled Wasm code, we don't want to do
reference count mutations for every compiled `local.{get,set}`, nor for
every function call. Therefore, we use a variation of **deferred reference
counting**, where we only mutate reference counts when storing
`VMExternRef`s somewhere that outlives the activation: into a global or
table. Simultaneously, we over-approximate the set of `VMExternRef`s that
are inside Wasm function activations. Periodically, we walk the stack at GC
safe points, and use stack map information to precisely identify the set of
`VMExternRef`s inside Wasm activations. Then we take the difference between
this precise set and our over-approximation, and decrement the reference
count for each of the `VMExternRef`s that are in our over-approximation but
not in the precise set. Finally, the over-approximation is replaced with the
precise set.
The `VMExternRefActivationsTable` implements the over-approximized set of
`VMExternRef`s referenced by Wasm activations. Calling a Wasm function and
passing it a `VMExternRef` moves the `VMExternRef` into the table, and the
compiled Wasm function logically "borrows" the `VMExternRef` from the
table. Similarly, `global.get` and `table.get` operations clone the gotten
`VMExternRef` into the `VMExternRefActivationsTable` and then "borrow" the
reference out of the table.
When a `VMExternRef` is returned to host code from a Wasm function, the host
increments the reference count (because the reference is logically
"borrowed" from the `VMExternRefActivationsTable` and the reference count
from the table will be dropped at the next GC).
For more general information on deferred reference counting, see *An
Examination of Deferred Reference Counting and Cycle Detection* by Quinane:
https://openresearch-repository.anu.edu.au/bitstream/1885/42030/2/hon-thesis.pdf
cc #929
Fixes #1804
4 years ago
|
|
|
|
|
|
|
[[example]]
|
|
|
|
name = "tokio"
|
|
|
|
required-features = ["wasmtime-wasi/tokio"]
|
|
|
|
|
|
|
|
[[bench]]
|
|
|
|
name = "instantiation"
|
|
|
|
harness = false
|
|
|
|
|
|
|
|
[[bench]]
|
|
|
|
name = "thread_eager_init"
|
|
|
|
harness = false
|
|
|
|
|
|
|
|
[[bench]]
|
|
|
|
name = "trap"
|
|
|
|
harness = false
|
|
|
|
|
|
|
|
[[bench]]
|
|
|
|
name = "call"
|
|
|
|
harness = false
|