* Remove all global state from the caching system
This commit is a continuation of an effort to remove usages of
`lazy_static!` and similar global state macros which can otherwise be
accomodated with passing objects around. Previously there was a global
cache system initialized per-process, but it was initialized in a bit of
a roundabout way and wasn't actually reachable from the `wasmtime` crate
itself. The changes here remove all global state, refactor many of the
internals in the cache system, and makes configuration possible through
the `wasmtime` crate.
Specifically some changes here are:
* Usage of `lazy_static!` and many `static` items in the cache module
have all been removed.
* Global `cache_config()`, `worker()`, and `init()` functions have all
been removed. Instead a `CacheConfig` is a "root object" which
internally owns its worker and passing around the `CacheConfig` is
required for cache usage.
* The `wasmtime::Config` structure has grown options to load and parse
cache files at runtime. Currently only loading files is supported,
although we can likely eventually support programmatically configuring
APIs as well.
* Usage of the `spin` crate has been removed and the dependency is removed.
* The internal `errors` field of `CacheConfig` is removed, instead
changing all relevant methods to return a `Result<()>` instead of
storing errors internally.
* Tests have all been updated with the new interfaces and APIs.
Functionally no real change is intended here. Usage of the `wasmtime`
CLI, for example, should still enable the cache by default.
* Fix lightbeam compilation
* Remove global state for trap registration
There's a number of changes brought about in this commit, motivated by a
few things. One motivation was to remove an instance of using
`lazy_static!` in an effort to remove global state and encapsulate it
wherever possible. A second motivation came when investigating a
slowly-compiling wasm module (a bit too slowly) where a good chunk of
time was spent in managing trap registrations.
The specific change made here is that `TrapRegistry` is now stored
inside of a `Compiler` instead of inside a global. Additionally traps
are "bulk registered" for a module rather than one-by-one. This form of
bulk-registration allows optimizing the locks used here, where a lock is
only held for a module at-a-time instead of once-per-function.
With these changes the "unregister" logic has also been tweaked a bit
here and there to continue to work. As a nice side effect the `Compiler`
type now has one fewer field that requires actual mutability and has
been updated for multi-threaded compilation, nudging us closer to a
world where we can support multi-threaded compilation. Yay!
In terms of performance improvements, a local wasm test file that
previously took 3 seconds to compile is now 10% faster to compile,
taking ~2.7 seconds now.
* Perform trap resolution after unwinding
This avoids taking locks in signal handlers which feels a bit iffy...
* Remove `TrapRegistration::dummy()`
Avoid an case where you're trying to lookup trap information from a
dummy module for something that happened in a different module.
* Tweak some comments
The intention of the `wasmtime` crate was to disable this verifier by
default, but it looks like cranelift actually has it turned on by
default which was making our documentation incorrect!
This was discovered by seeing a number of timeouts when fuzzing. The
debug verifier is great for fuzzing, however, so fuzzing is updated to
enable this unconditionally, meaning we'll still have timeouts. For
general users though this should make the documentation correct that the
`wasmtime` crate, by default, disables the debug verifier.
* Reimplement `wasmtime-wasi` on top of `wasmtime`
This commit reimplements the `wasmtime-wasi` crate on top of the
`wasmtime` API crate, instead of being placed on top of the `wasmtime-*`
family of internal crates. The purpose here is to continue to exercise
the API as well as avoid usage of internals wherever possible and
instead use the safe API as much as possible.
The `wasmtime-wasi` crate's API has been updated as part of this PR as
well. The general outline of it is now:
* Each module snapshot has a `WasiCtxBuilder`, `WasiCtx`, and `Wasi`
type.
* The `WasiCtx*` types are reexported from `wasi-common`.
* The `Wasi` type is synthesized by the `wig` crate's procedural macro
* The `Wasi` type exposes one constructor which takes a `Store` and a
`WasiCtx`, and produces a `Wasi`
* Each `Wasi` struct fields for all the exported functions in that wasi
module. They're all public an they all have type `wasmtime::Func`
* The `Wasi` type has a `get_export` method to fetch an struct field by
name.
The intention here is that we can continue to make progress on #727 by
integrating WASI construction into the `Instance::new` experience, but
it requires everything to be part of the same system!
The main oddity required by the `wasmtime-wasi` crate is that it needs
access to the caller's `memory` export, if any. This is currently done
with a bit of a hack and is expected to go away once interface types are
more fully baked in.
* Remove now no-longer-necessary APIs from `wasmtime`
* rustfmt
* Rename to from_abi
* Move `Func` to its own file
* Support `Func` imports with zero shims
This commit extends the `Func` type in the `wasmtime` crate with static
`wrap*` constructors. The goal of these constructors is to create a
`Func` type which has zero shims associated with it, creating as small
of a layer as possible between wasm code and calling imported Rust code.
This is achieved by creating an `extern "C"` shim function which matches
the ABI of what Cranelift will generate, and then the host function is
passed directly into an `InstanceHandle` to get called later. This also
enables enough inlining opportunities that LLVM will be able to see all
functions and inline everything to the point where your function is
called immediately from wasm, no questions asked.
Whenever we enter wasm code we need to verify that the correct number
and the correct types of arguments were passed in, lest we misinterpret
bits!
Closes#52
* Remove another thread local in `instance.rs`
This commit removes another usage of `thread_local!` in the continued
effort to centralize all thread-local state per-call (or basically state
needed for traps) in one location. This removal is targeted at the
support for custom signal handlers on instances, removing the previous
stack of instances with instead a linked list of instances.
The `with_signals_on` method is no longer necessary (since it was always
called anyway) and is inferred from the first `vmctx` argument of the
entrypoints into wasm. These functions establish a linked list of
instances on the stack, if needed, to handle signals when they happen.
This involved some refactoring where some C++ glue was moved into Rust,
so now Rust handles a bit more of the signal handling logic.
* Update some inline docs about `HandleTrap`
* Improve panics/traps from imported functions
This commit performs a few refactorings and fixes a bug as well. The
changes here are:
* The `thread_local!` in the `wasmtime` crate for trap information is
removed. The thread local in the `wasmtime_runtime` crate is now
leveraged to transmit trap information.
* Panics in user-provided functions are now caught explicitly to be
carried across JIT code manually. Getting Rust panics unwinding
through JIT code is pretty likely to be super tricky and difficult to
do, so in the meantime we can get by with catching panics and resuming
the panic once we've resumed in Rust code.
* Various take/record trap apis have all been removed in favor of
working directly with `Trap` objects, where the internal trap object
has been expanded slightly to encompass user-provided errors as well.
This borrows a bit #839 and otherwise will...
Closes#848
* Rename `r#return` to `ret`
* Support parsing the text format in `wasmtime` crate
This commit adds support to the `wasmtime::Module` type to parse the
text format. This is often quite convenient to support in testing or
tinkering with the runtime. Additionally the `wat` parser is pretty
lightweight and easy to add to builds, so it's relatively easy for us to
support as well!
The exact manner that this is now supported comes with a few updates to
the existing API:
* A new optional feature of the `wasmtime` crate, `wat`, has been added.
This is enabled by default.
* The `Module::new` API now takes `impl AsRef<[u8]>` instead of just
`&[u8]`, and when the `wat` feature is enabled it will attempt to
interpret it either as a wasm binary or as the text format. Note that
this check is quite cheap since you just check the first byte.
* A `Module::from_file` API was added as a convenience to parse a file
from disk, allowing error messages for `*.wat` files on disk to be a
bit nicer.
* APIs like `Module::new_unchecked` and `Module::validate` remain
unchanged, they require the binary format to be called.
The intention here is to make this as convenient as possible for new
developers of the `wasmtime` crate. By changing the default behavior
though this has ramifications such as, for example, supporting the text
format implicitly through the C API now.
* Handle review comments
* Update more tests to avoid usage of `wat` crate
* Go back to unchecked for now in wasm_module_new
Looks like C# tests rely on this?
* Reel in unsafety around `InstanceHandle`
This commit is an attempt, or at least is targeted at being a start, at
reeling in the unsafety around the `InstanceHandle` type. Currently this
type represents a sort of moral `Rc<Instance>` but is a bit more
specialized since the underlying memory is allocated through mmap.
Additionally, though, `InstanceHandle` exposes a fundamental flaw in its
safety by safetly allowing mutable access so long as you have `&mut
InstanceHandle`. This type, however, is trivially created by simply
cloning a `InstanceHandle` to get an owned reference. This means that
`&mut InstanceHandle` does not actually provide any guarantees about
uniqueness, so there's no more safety than `&InstanceHandle` itself.
This commit removes all `&mut self` APIs from `InstanceHandle`,
additionally removing some where `&self` was `unsafe` and `&mut self`
was safe (since it was trivial to subvert this "safety"). In doing so
interior mutability patterns are now used much more extensively through
structures such as `Table` and `Memory`. Additionally a number of
methods were refactored to be a bit clearer and use helper functions
where possible.
This is a relatively large commit unfortunately, but it snowballed very
quickly into touching quite a few places. My hope though is that this
will prevent developers working on wasmtime internals as well as
developers still yet to migrate to the `wasmtime` crate from falling
into trivial unsafe traps by accidentally using `&mut` when they can't.
All existing users relying on `&mut` will need to migrate to some form
of interior mutability, such as using `RefCell` or `Cell`.
This commit also additionally marks `InstanceHandle::new` as an `unsafe`
function. The rationale for this is that the `&mut`-safety is only the
beginning for the safety of `InstanceHandle`. In general the wasmtime
internals are extremely unsafe and haven't been audited for appropriate
usage of `unsafe`. Until that's done it's hoped that we can warn users
with this `unsafe` constructor and otherwise push users to the
`wasmtime` crate which we know is safe.
* Fix windows build
* Wrap up mutable memory state in one structure
Rather than having separate fields
* Use `Cell::set`, not `Cell::replace`, where possible
* Add a helper function for offsets from VMContext
* Fix a typo from merging
* rustfmt
* Use try_from, not as
* Tweak style of some setters
* Improve handling of strings for backtraces
Largely avoid storing strings at all in the `wasmtime-*` internal
crates, and instead only store strings in a separate global cache
specific to the `wasmtime` crate itself. This global cache is inserted
and removed from dynamically as modules are created and deallocated, and
the global cache is consulted whenever a `Trap` is created to
symbolicate any wasm frames.
This also avoids the need to thread `module_name` through the jit crates
and back, and additionally removes the need for `ModuleSyncString`.
* Run rustfmt
This commit removes the `signature_cache` field from the `Store` type
and performs a few internal changes which are aimed to be a bit forward
looking towards #777, making `Store` threadsafe.
The changes made here are:
* The `SignatureRegistry` internal type now contains the reverse map
that `signature_cache` was serving to do. This is populated on calls
to `register` automatically and is accompanied by a `lookup` method as
well.
* The `register_wasmtime_signature` and `lookup_wasmtime_signature`
methods were removed from `Store` and now instead work by using the
`Compiler::signatures` field.
* The `SignatureRegistry` type was updated to have interior mutability.
The global `Compiler` type is highly likely to get shared across many
threads through `Store`, so it needs some form of lock somewhere for
mutation of the registry of signatures and this commit opts to put it
inside `SignatureRegistry` which will eventually allow for the removal
of most `&mut self` method on `Compiler`.
* Replace the global-exports mechanism with a caller-vmctx mechanism.
This eliminates the global exports mechanism, and instead adds a
caller-vmctx argument to wasm functions so that WASI can obtain the
memory and other things from the caller rather than looking them up in a
global registry.
This replaces #390.
* Fixup some merge conflicts
* Rustfmt
* Ensure VMContext is aligned to 16 bytes
With the removal of `global_exports` it "just so happens" that this
isn't happening naturally any more.
* Fixup some bugs with double vmctx in wasmtime crate
* Trampoline stub needed adjusting
* Use pointer type instead of always using I64 for caller vmctx
* Don't store `ir::Signature` in `Func` since we don't know the pointer
size at creation time.
* Skip the first 2 arguments in IR signatures since that's the two vmctx
parameters.
* Update cranelift to 0.56.0
* Handle more merge conflicts
* Rustfmt
Co-authored-by: Alex Crichton <alex@alexcrichton.com>
* Document and update the API of the `externals.rs` module
This commit ensures that all public methods and items are documented in
the `externals.rs` module, notably all external values that can be
imported and exported in WebAssembly. Along the way this also tidies up
the API and fixes a few bugs:
* `Global::new` now returns a `Result` and fails if the provided value
does not match the type of the global.
* `Global::set` now returns a `Result` and fails if the global is either
immutable or the provided value doesn't match the type of the global.
* `Table::new` now fails if the provided initializer does not match the
element type.
* `Table::get` now returns `Option<Val>` instead of implicitly returning
null.
* `Table::set` now returns `Result<()>`, returning an error on out of
bounds or if the input type is of the wrong type.
* `Table::grow` now returns `Result<u32>`, returning the previous number
of table elements if succesful or an error if the maximum is reached
or the initializer value is of the wrong type. Additionally a bug was
fixed here where if the wrong initializer was provided the table would
be grown still, but initialization would fail.
* `Memory::data` was renamed to `Memory::data_unchecked_mut`.
Additionally `Memory::data_unchecked` was added. Lots of caveats were
written down about how using the method can go wrong.
* `Memory::grow` now returns `Result<u32>`, returning an error if growth
fails or the number of pages previous the growth if successful.
* Run rustfmt
* Fix another test
* Update crates/api/src/externals.rs
Co-Authored-By: Sergei Pepyakin <s.pepyakin@gmail.com>
Co-authored-by: Sergei Pepyakin <s.pepyakin@gmail.com>
* Document the `wasmtime::Instance` APIs
This documents oddities like the import list and export list and how to
match them all up. Addtionally this largely just expands all the docs
related to `Instance` to get filled out.
This also moves the `set_signal_handler` functions into
platform-specific modules in order to follow Rust idioms about how to
expose platform-specific information. Additionally the methods are
marked `unsafe` because I figure anything having to do with signal
handling is `unsafe` inherently. I don't actually know what these
functions do, so they're currently still undocumented.
* Fix build of python bindings
* Fix some rebase conflicts
* Move compilation into Module from Instance.
* Fix fuzzing
* Use wasmtime::Module in fuzzing crates
Instead of wasmtime_jit.
* Compile eagerly.
* Review fixes.
* Always use the saved name.
* Preserve the former behavior for fuzzing oracle
* Remove the `Context` type from `wasmtime`
This hasn't really ended up being used in all that many places and the
dependencies on it were pretty minimal. This commit removes it in favor
of simplifying its various users a bit and/or leveraging the
`Engine`/`Store` structures where possible.
* Run rustfmt
* Preserve full native stack traces in errors
This commit builds on #759 by performing a few refactorings:
* The `backtrace` crate is updated to 0.3.42 which incorporates the
Windows-specific stack-walking code, so that's no longer needed.
* A full `backtrace::Backtrace` type is held in a trap at all times.
* The trap structures in the `wasmtime-*` internal crates were
refactored a bit to preserve more information and deal with raw
values rather than converting between various types and strings.
* The `wasmtime::Trap` type has been updated with these various changes.
Eventually I think we'll want to likely render full stack traces (and/or
partial wasm ones) into error messages, but for now that's left as-is
and we can always improve it later. I suspect the most relevant thing we
need to do is to implement function name symbolication for wasm
functions first, and then afterwards we can incorporate native function
names!
* Fix some test suite assertions
* Move the C API to a separate crate
This commit moves the C API from `crates/api/src/wasm.rs` to
`crates/capi/src/lib.rs` to be located in a separate crate. There's a
number of reasons for this:
* When a Rust program depends on the `wasmtime` crate, there's no need
to compile in the C API.
* This should improve compile times of the `wasmtime` crate since it's
not producing artifacts which aren't always used.
* The development of the C API can be guaranteed to only use the public
API of the `wasmtime` crate itself.
Some CI pieces are tweaked and this overall shouldn't have much impact
on users, it's intended that it's a cleanup/speedup for developers!
* Disable rustdoc/tests for capi
* Review feedback
* Add back in accidentally deleted comment
* More renamings
* Try to fix dotnet build
* Don't require `Store` in `Instance` constructor
This can be inferred from the `Module` argument. Additionally add a
`store` accessor to an `Instance` in case it's needed to instantiate
another `Module`.
cc #708
* Update more constructors
* Fix a doctest
* Don't ignore store in `wasm_instance_new`
* Run rustfmt
In preparation for eventual support for wasm interface types this commit
moves around a few panics internally inside of conversions between the
`wasmtime` crate and the underlying jit support crates. This should have
any immediately-visible user changes, but the goal is that this'll help
support interface types which means `wasmtime` will have types that are
not supported by wasmtime itself and we'll be able to more gracefully
support that with error messages instead of accidental panics.
* Update to the latest spec_testsuite and dependencies.
Update to target-lexicon 0.10, cranelift 0.54, wast 0.6, faerie 0.14,
and the latest spec_testsuite.
For wast and cranelift-wasm, update the code for API changes.
* Factor out the code for matching f32, f64, and v128.
This takes the idea from #802 to split out `f32_matches`, `f64_matches`,
and `v128_matches` functions, which better factor out the matching
functionality between scalar and vector.
This continues #788 and literally removes the type from the public API
of the `wasmtime` crate, making it inaccessible to the outside world.
Now it's purely an implementation detail, yay!
A few small updates to module creation in preparation for a future PR
which is a bit more invasive here with interface types.
* Move `read_imports_and_exports` to an instance method which configures
fields directly rather than returning a number of fields.
* Call between constructors as much as possible.
* Leverage `Rc::get_mut` which we know will work at module creation time
since we have the only reference.
* Only require `str` in `new_with_name`
It's a bit more idiomatic to have APIs require `&str` rather than
`String`, and the allocation doesn't matter much here since creating a
`Module` is pretty expensive anyway.
* Update a test
* Remove `HostRef` from the `wasmtime` public API
This commit removes all remaining usages of `HostRef` in the public API
of the `wasmtime` crate. This involved a number of API decisions such
as:
* None of `Func`, `Global`, `Table`, or `Memory` are wrapped in `HostRef`
* All of `Func`, `Global`, `Table`, and `Memory` implement `Clone` now.
* Methods called `type` are renamed to `ty` to avoid typing `r#type`.
* Methods requiring mutability for external items now no longer require
mutability. The mutable reference here is sort of a lie anyway since
the internals are aliased by the underlying module anyway. This
affects:
* `Table::set`
* `Table::grow`
* `Memory::grow`
* `Instance::set_signal_handler`
* The `Val::FuncRef` type is now no longer automatically coerced to
`AnyRef`. This is technically a breaking change which is pretty bad,
but I'm hoping that we can live with this interim state while we sort
out the `AnyRef` story in general.
* The implementation of the C API was refactored and updated in a few
locations to account for these changes:
* Accessing the exports of an instance are now cached to ensure we
always hand out the same `HostRef` values.
* `wasm_*_t` for external values no longer have internal cache,
instead they all wrap `wasm_external_t` and have an unchecked
accessor for the underlying variant (since the type is proof that
it's there). This makes casting back and forth much more trivial.
This is all related to #708 and while there's still more work to be done
in terms of documentation, this is the major bulk of the rest of the
implementation work on #708 I believe.
* More API updates
* Run rustfmt
* Fix a doc test
* More test updates
This commit fixes the `wasmtime::Instance` instantiation API when
imports have the same name but might be imported under different types.
This is handled in the API by listing imports as a list instead of as a
name map, but they were interpreted as a name map under the hood causing
collisions.
This commit now keeps track of the index used to define each import, and
the index is passed through in the `Resolver`. Existing implementaitons
of `Resolver` all ignore this, but the API now uses it exclusivley to
match up `Extern` definitions to imports.
* Per Instance signal handler
* add custom signal handler test
* add instance signal handling to callable.rs
* extend signal handler test to test callable.rs
* test multiple instances, multiple signal handlers
* support more than one current instance
import_calling_export.rs is a good example of why this is needed:
execution switches from one instance to another before the first one has
finished running
* add another custom signal handler test case
* move and update custom signal handler tests
* fmt
* fix libc version to 0.2
* call the correct instance signal handler
We keep a stack of instances so should call last() not first().
* move custom signal handler test to top level dir
* windows/mac signal handling wip
* os-specific signal handling wip
* disable custom signal handler test on windows
* fmt
* unify signal handling on mac and linux
This commit continues previous work and also #708 by removing the need
to use `HostRef<Module>` in the API of the `wasmtime` crate. The API
changes performed here are:
* The `Module` type is now itself internally reference counted.
* The `Module::store` function now returns the `Store` that was used to
create a `Module`
* Documentation for `Module` and its methods have been expanded.
* Remove the need for `HostRef<Module>`
This commit continues previous work and also #708 by removing the need
to use `HostRef<Module>` in the API of the `wasmtime` crate. The API
changes performed here are:
* The `Module` type is now itself internally reference counted.
* The `Module::store` function now returns the `Store` that was used to
create a `Module`
* Documentation for `Module` and its methods have been expanded.
* Fix compliation of test programs harness
* Fix the python extension
* Update `CodeMemory` to be `Send + Sync`
This commit updates the `CodeMemory` type in wasmtime to be both `Send`
and `Sync` by updating the implementation of `Mmap` to not store raw
pointers. This avoids the need for an `unsafe impl` and leaves the
unsafety as it is currently.
* Fix a typo
* Remove unsafety from `Trap` API
This commit removes the `unsafe impl Send` for `Trap` by removing the
internal `HostRef` and leaving `HostRef` entirely as an implementation
detail of the C API.
cc #708
* Run rustfmt
* Remove the need for `HostRef<Store>`
This commit goes through the public API of the `wasmtime` crate and
removes the need for `HostRef<Store>`, as discussed in #708. This commit
is accompanied with a few changes:
* The `Store` type now also implements `Default`, creating a new
`Engine` with default settings and returning that.
* The `Store` type now implements `Clone`, and is documented as being a
"cheap clone" aka being reference counted. As before there is no
supported way to create a deep clone of a `Store`.
* All APIs take/return `&Store` or `Store` instead of `HostRef<Store>`,
and `HostRef<T>` is left as purely a detail of the C API.
* The `global_exports` function is tagged as `#[doc(hidden)]` for now
while we await its removal.
* The `Store` type is not yet `Send` nor `Sync` due to the usage of
`global_exports`, but it is intended to become so eventually.
* Touch up comments on some examples
* Run rustfmt