wasmtime/
runtime.rs

1// Wasmtime's runtime has lots of fiddly bits where we're doing operations like
2// casting between wasm i32/i64 and host `usize` values. There's also in general
3// just lots of pieces of low-level manipulation of memory and internals of VM
4// runtime state. To help keep all the integer casts correct be a bit more
5// strict than the default settings to help weed out bugs ahead of time.
6//
7// This inevitably leads to wordier code than might otherwise be used because,
8// for example, `u64 as usize` is warned against and will be an error on CI.
9// This happens pretty frequently and needs to be replaced with `val.try_into()`
10// or `usize::try_from(val)` where the error is handled. In some cases the
11// correct thing to do is to `.unwrap()` the error to indicate a fatal mistake,
12// but in some cases the correct thing is to propagate the error.
13//
14// Some niche cases that explicitly want truncation are recommended to have a
15// function along the lines of
16//
17//     #[allow(clippy::cast_possible_truncation)]
18//     fn truncate_i32_to_i8(a: i32) -> i8 { a as i8 }
19//
20// as this explicitly indicates the intent of truncation is desired. Other
21// locations should use fallible conversions.
22//
23// If performance is absolutely critical then it's recommended to use `#[allow]`
24// with a comment indicating why performance is critical as well as a short
25// explanation of why truncation shouldn't be happening at runtime. This
26// situation should be pretty rare though.
27#![warn(clippy::cast_possible_truncation)]
28
29#[macro_use]
30pub(crate) mod func;
31
32pub(crate) mod code;
33pub(crate) mod code_memory;
34#[cfg(feature = "debug")]
35pub(crate) mod debug;
36#[cfg(feature = "gc")]
37pub(crate) mod exception;
38pub(crate) mod externals;
39#[cfg(feature = "async")]
40pub(crate) mod fiber;
41pub(crate) mod gc;
42pub(crate) mod instance;
43pub(crate) mod instantiate;
44pub(crate) mod limits;
45pub(crate) mod linker;
46pub(crate) mod memory;
47pub(crate) mod module;
48#[cfg(feature = "debug-builtins")]
49pub(crate) mod native_debug;
50pub(crate) mod resources;
51pub(crate) mod store;
52pub(crate) mod trampoline;
53pub(crate) mod trap;
54pub(crate) mod type_registry;
55pub(crate) mod types;
56pub(crate) mod uninhabited;
57pub(crate) mod v128;
58pub(crate) mod values;
59pub(crate) mod vm;
60
61#[cfg(feature = "component-model")]
62pub mod component;
63
64cfg_if::cfg_if! {
65    if #[cfg(miri)] {
66        // no extensions on miri
67    } else if #[cfg(not(feature = "std"))] {
68        // no extensions on no-std
69    } else if #[cfg(unix)] {
70        pub mod unix;
71    } else if #[cfg(windows)] {
72        pub mod windows;
73    } else {
74        // ... unknown os!
75    }
76}
77
78pub use code_memory::CodeMemory;
79#[cfg(feature = "debug")]
80pub use debug::*;
81#[cfg(feature = "gc")]
82pub use exception::*;
83pub use externals::*;
84pub use func::*;
85pub use gc::*;
86pub use instance::{Instance, InstancePre};
87pub use instantiate::CompiledModule;
88pub use limits::*;
89pub use linker::*;
90pub use memory::*;
91pub use module::{Module, ModuleExport};
92pub use resources::*;
93#[cfg(all(feature = "async", feature = "call-hook"))]
94pub use store::CallHookHandler;
95pub use store::{
96    AsContext, AsContextMut, CallHook, Store, StoreContext, StoreContextMut, UpdateDeadline,
97};
98pub use trap::*;
99pub use types::*;
100pub use v128::V128;
101pub use values::*;
102
103pub(crate) use uninhabited::*;
104
105#[cfg(feature = "pooling-allocator")]
106pub use vm::{PoolConcurrencyLimitError, PoolingAllocatorMetrics};
107
108#[cfg(feature = "profiling")]
109mod profiling;
110#[cfg(feature = "profiling")]
111pub use profiling::GuestProfiler;
112
113#[cfg(feature = "async")]
114pub(crate) mod stack;
115#[cfg(feature = "async")]
116pub use stack::*;
117
118#[cfg(feature = "coredump")]
119mod coredump;
120#[cfg(feature = "coredump")]
121pub use coredump::*;
122
123#[cfg(feature = "wave")]
124mod wave;
125
126fn _assertions_runtime() {
127    use crate::_assert_send_and_sync;
128
129    #[cfg(feature = "async")]
130    fn _assert_send<T: Send>(_t: T) {}
131
132    _assert_send_and_sync::<Caller<'_, ()>>();
133    _assert_send_and_sync::<ExternRef>();
134    _assert_send_and_sync::<(Func, TypedFunc<(), ()>, Global, Table, Memory)>();
135    _assert_send_and_sync::<Instance>();
136    _assert_send_and_sync::<InstancePre<()>>();
137    _assert_send_and_sync::<InstancePre<*mut u8>>();
138    _assert_send_and_sync::<Linker<()>>();
139    _assert_send_and_sync::<Linker<*mut u8>>();
140    _assert_send_and_sync::<Module>();
141    _assert_send_and_sync::<Store<()>>();
142    _assert_send_and_sync::<StoreContext<'_, ()>>();
143    _assert_send_and_sync::<StoreContextMut<'_, ()>>();
144
145    #[cfg(feature = "async")]
146    fn _call_async(s: &mut Store<()>, f: Func) {
147        _assert_send(f.call_async(&mut *s, &[], &mut []))
148    }
149    #[cfg(feature = "async")]
150    fn _typed_call_async(s: &mut Store<()>, f: TypedFunc<(), ()>) {
151        _assert_send(f.call_async(&mut *s, ()))
152    }
153    #[cfg(feature = "async")]
154    fn _instantiate_async(s: &mut Store<()>, m: &Module) {
155        _assert_send(Instance::new_async(s, m, &[]))
156    }
157}