1 // Flags to either `wasmtime_mmap_{new,remap}` or `wasmtime_mprotect`.
2 
3 /// Indicates that the memory region should be readable.
4 #[cfg(has_virtual_memory)]
5 pub const WASMTIME_PROT_READ: u32 = 1 << 0;
6 /// Indicates that the memory region should be writable.
7 #[cfg(has_virtual_memory)]
8 pub const WASMTIME_PROT_WRITE: u32 = 1 << 1;
9 /// Indicates that the memory region should be executable.
10 #[cfg(has_virtual_memory)]
11 pub const WASMTIME_PROT_EXEC: u32 = 1 << 2;
12 
13 #[cfg(has_virtual_memory)]
14 pub use WASMTIME_PROT_EXEC as PROT_EXEC;
15 #[cfg(has_virtual_memory)]
16 pub use WASMTIME_PROT_READ as PROT_READ;
17 #[cfg(has_virtual_memory)]
18 pub use WASMTIME_PROT_WRITE as PROT_WRITE;
19 
20 /// Handler function for traps in Wasmtime passed to `wasmtime_init_traps`.
21 ///
22 /// This function is invoked whenever a trap is caught by the system. For
23 /// example this would be invoked during a signal handler on Linux. This
24 /// function is passed a number of parameters indicating information about the
25 /// trap:
26 ///
27 /// * `ip` - the instruction pointer at the time of the trap.
28 /// * `fp` - the frame pointer register's value at the time of the trap.
29 /// * `has_faulting_addr` - whether this trap is associated with an access
30 ///   violation (e.g. a segfault) meaning memory was accessed when it shouldn't
31 ///   be. If this is `true` then the next parameter is filled in.
32 /// * `faulting_addr` - if `has_faulting_addr` is true then this is the address
33 ///   that was attempted to be accessed. Otherwise this value is not used.
34 ///
35 /// If this function returns then the trap was not handled by Wasmtime. This
36 /// means that it's left up to the embedder how to deal with the trap/signal
37 /// depending on its default behavior. This could mean forwarding to a
38 /// non-Wasmtime handler, aborting the process, logging then crashing, etc. The
39 /// meaning of a trap that's not handled by Wasmtime depends on the context in
40 /// which the trap was generated.
41 ///
42 /// When this function does not return it's because a native exception handler
43 /// was resumed to.
44 #[cfg(has_native_signals)]
45 #[expect(non_camel_case_types, reason = "matching C conventions")]
46 pub type wasmtime_trap_handler_t =
47     extern "C" fn(ip: usize, fp: usize, has_faulting_addr: bool, faulting_addr: usize);
48 
49 /// Abstract pointer type used in the `wasmtime_memory_image_*` APIs which
50 /// is defined by the embedder.
51 #[cfg(has_virtual_memory)]
52 #[expect(non_camel_case_types, reason = "matching C conventions")]
53 pub enum wasmtime_memory_image {}
54 
55 unsafe extern "C" {
56     /// Creates a new virtual memory mapping of the `size` specified with
57     /// protection bits specified in `prot_flags`.
58     ///
59     /// Memory can be lazily committed.
60     ///
61     /// Stores the base pointer of the new mapping in `ret` on success.
62     ///
63     /// Returns 0 on success and an error code on failure.
64     ///
65     /// Similar to `mmap(0, size, prot_flags, MAP_PRIVATE, 0, -1)` on Linux.
66     #[cfg(has_virtual_memory)]
wasmtime_mmap_new(size: usize, prot_flags: u32, ret: &mut *mut u8) -> i3267     pub fn wasmtime_mmap_new(size: usize, prot_flags: u32, ret: &mut *mut u8) -> i32;
68 
69     /// Remaps the virtual memory starting at `addr` going for `size` bytes to
70     /// the protections specified with a new blank mapping.
71     ///
72     /// This will unmap any prior mappings and decommit them. New mappings for
73     /// anonymous memory are used to replace these mappings and the new area
74     /// should have the protection specified by `prot_flags`.
75     ///
76     /// Returns 0 on success and an error code on failure.
77     ///
78     /// Similar to `mmap(addr, size, prot_flags, MAP_PRIVATE | MAP_FIXED, 0, -1)` on Linux.
79     #[cfg(has_virtual_memory)]
wasmtime_mmap_remap(addr: *mut u8, size: usize, prot_flags: u32) -> i3280     pub fn wasmtime_mmap_remap(addr: *mut u8, size: usize, prot_flags: u32) -> i32;
81 
82     /// Unmaps memory at the specified `ptr` for `size` bytes.
83     ///
84     /// The memory should be discarded and decommitted and should generate a
85     /// segfault if accessed after this function call.
86     ///
87     /// Returns 0 on success and an error code on failure.
88     ///
89     /// Similar to `munmap` on Linux.
90     #[cfg(has_virtual_memory)]
wasmtime_munmap(ptr: *mut u8, size: usize) -> i3291     pub fn wasmtime_munmap(ptr: *mut u8, size: usize) -> i32;
92 
93     /// Configures the protections associated with a region of virtual memory
94     /// starting at `ptr` and going to `size`.
95     ///
96     /// Returns 0 on success and an error code on failure.
97     ///
98     /// Similar to `mprotect` on Linux.
99     #[cfg(has_virtual_memory)]
wasmtime_mprotect(ptr: *mut u8, size: usize, prot_flags: u32) -> i32100     pub fn wasmtime_mprotect(ptr: *mut u8, size: usize, prot_flags: u32) -> i32;
101 
102     /// Returns the page size, in bytes, of the current system.
103     #[cfg(has_virtual_memory)]
wasmtime_page_size() -> usize104     pub fn wasmtime_page_size() -> usize;
105 
106     /// Initializes trap-handling logic for this platform.
107     ///
108     /// Wasmtime's implementation of WebAssembly relies on the ability to catch
109     /// signals/traps/etc. For example divide-by-zero may raise a machine
110     /// exception. Out-of-bounds memory accesses may also raise a machine
111     /// exception. This function is used to initialize trap handling.
112     ///
113     /// The `handler` provided is a function pointer to invoke whenever a trap
114     /// is encountered. The `handler` is invoked whenever a trap is caught by
115     /// the system.
116     ///
117     /// Returns 0 on success and an error code on failure.
118     #[cfg(has_native_signals)]
wasmtime_init_traps(handler: wasmtime_trap_handler_t) -> i32119     pub fn wasmtime_init_traps(handler: wasmtime_trap_handler_t) -> i32;
120 
121     /// Attempts to create a new in-memory image of the `ptr`/`len` combo which
122     /// can be mapped to virtual addresses in the future.
123     ///
124     /// On success the returned `wasmtime_memory_image` pointer is stored into `ret`.
125     /// This value stored can be `NULL` to indicate that an image cannot be
126     /// created but no failure occurred. The structure otherwise will later be
127     /// deallocated with `wasmtime_memory_image_free` and
128     /// `wasmtime_memory_image_map_at` will be used to map the image into new
129     /// regions of the address space.
130     ///
131     /// The `ptr` and `len` arguments are only valid for this function call, if
132     /// the image needs to refer to them in the future then it must make a copy.
133     ///
134     /// Both `ptr` and `len` are guaranteed to be page-aligned.
135     ///
136     /// Returns 0 on success and an error code on failure. Note that storing
137     /// `NULL` into `ret` is not considered a failure, and failure is used to
138     /// indicate that something fatal has happened and Wasmtime will propagate
139     /// the error upwards.
140     #[cfg(has_virtual_memory)]
wasmtime_memory_image_new( ptr: *const u8, len: usize, ret: &mut *mut wasmtime_memory_image, ) -> i32141     pub fn wasmtime_memory_image_new(
142         ptr: *const u8,
143         len: usize,
144         ret: &mut *mut wasmtime_memory_image,
145     ) -> i32;
146 
147     /// Maps the `image` provided to the virtual address at `addr` and `len`.
148     ///
149     /// This semantically should make it such that `addr` and `len` looks the
150     /// same as the contents of what the memory image was first created with.
151     /// The mappings of `addr` should be private and changes do not reflect back
152     /// to `wasmtime_memory_image`.
153     ///
154     /// In effect this is to create a copy-on-write mapping at `addr`/`len`
155     /// pointing back to the memory used by the image originally.
156     ///
157     /// Note that the memory region will be unmapped with `wasmtime_munmap` in
158     /// the future.
159     ///
160     /// Aborts the process on failure.
161     #[cfg(has_virtual_memory)]
wasmtime_memory_image_map_at( image: *mut wasmtime_memory_image, addr: *mut u8, len: usize, ) -> i32162     pub fn wasmtime_memory_image_map_at(
163         image: *mut wasmtime_memory_image,
164         addr: *mut u8,
165         len: usize,
166     ) -> i32;
167 
168     /// Deallocates the provided `wasmtime_memory_image`.
169     ///
170     /// Note that mappings created from this image are not guaranteed to be
171     /// deallocated and/or unmapped before this is called.
172     #[cfg(has_virtual_memory)]
wasmtime_memory_image_free(image: *mut wasmtime_memory_image)173     pub fn wasmtime_memory_image_free(image: *mut wasmtime_memory_image);
174 
175     /// Wasmtime requires a single pointer's space of TLS to be used at runtime,
176     /// and this function returns the current value of the TLS variable.
177     ///
178     /// This value should default to `NULL`.
wasmtime_tls_get() -> *mut u8179     pub fn wasmtime_tls_get() -> *mut u8;
180 
181     /// Sets the current TLS value for Wasmtime to the provided value.
182     ///
183     /// This value should be returned when later calling `wasmtime_tls_get`.
wasmtime_tls_set(ptr: *mut u8)184     pub fn wasmtime_tls_set(ptr: *mut u8);
185 
186     /// Frees a synchronization lock.
187     ///
188     /// May be called on a lock that was never used (still has a zero pattern).
189     /// The implementor must handle this case gracefully.
190     #[cfg(has_custom_sync)]
wasmtime_sync_lock_free(lock: *mut usize)191     pub fn wasmtime_sync_lock_free(lock: *mut usize);
192 
193     /// Acquires an exclusive lock.
194     ///
195     /// If the lock is uninitialized (zero pattern), it will be initialized lazily.
196     /// This function blocks until the lock is acquired.
197     /// Must be paired with [`wasmtime_sync_lock_release`].
198     #[cfg(has_custom_sync)]
wasmtime_sync_lock_acquire(lock: *mut usize)199     pub fn wasmtime_sync_lock_acquire(lock: *mut usize);
200 
201     /// Releases an exclusive lock previously acquired with [`wasmtime_sync_lock_acquire`].
202     #[cfg(has_custom_sync)]
wasmtime_sync_lock_release(lock: *mut usize)203     pub fn wasmtime_sync_lock_release(lock: *mut usize);
204 
205     /// Acquires a read lock on an RwLock.
206     ///
207     /// If the lock is uninitialized (zero pattern), it will be initialized lazily.
208     /// Multiple readers can hold the lock simultaneously.
209     /// Must be paired with [`wasmtime_sync_rwlock_read_release`].
210     #[cfg(has_custom_sync)]
wasmtime_sync_rwlock_read(lock: *mut usize)211     pub fn wasmtime_sync_rwlock_read(lock: *mut usize);
212 
213     /// Releases a read lock previously acquired with [`wasmtime_sync_rwlock_read`].
214     #[cfg(has_custom_sync)]
wasmtime_sync_rwlock_read_release(lock: *mut usize)215     pub fn wasmtime_sync_rwlock_read_release(lock: *mut usize);
216 
217     /// Acquires a write lock on an RwLock.
218     ///
219     /// If the lock is uninitialized (zero pattern), it will be initialized lazily.
220     /// Only one writer can hold the lock, and no readers can be present.
221     /// Must be paired with [`wasmtime_sync_rwlock_write_release`].
222     #[cfg(has_custom_sync)]
wasmtime_sync_rwlock_write(lock: *mut usize)223     pub fn wasmtime_sync_rwlock_write(lock: *mut usize);
224 
225     /// Releases a write lock previously acquired with [`wasmtime_sync_rwlock_write`].
226     #[cfg(has_custom_sync)]
wasmtime_sync_rwlock_write_release(lock: *mut usize)227     pub fn wasmtime_sync_rwlock_write_release(lock: *mut usize);
228 
229     /// Frees an RwLock.
230     ///
231     /// May be called on a lock that was never used (still has a zero pattern).
232     /// The implementor must handle this case gracefully.
233     #[cfg(has_custom_sync)]
wasmtime_sync_rwlock_free(lock: *mut usize)234     pub fn wasmtime_sync_rwlock_free(lock: *mut usize);
235 }
236