wasmtime 42.0.2

High-level API to expose the Wasmtime runtime
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
use crate::Engine;
use crate::Module;
use crate::Result;
use crate::module::ModuleRegistry;
use crate::vm::ModuleMemoryImageSource;
use crate::{code_memory::CodeMemory, type_registry::TypeCollection};
#[cfg(feature = "debug")]
use alloc::boxed::Box;
use alloc::sync::Arc;
use core::ops::{Add, Range, Sub};
use wasmtime_environ::DefinedFuncIndex;
use wasmtime_environ::ModuleTypes;
#[cfg(feature = "component-model")]
use wasmtime_environ::component::ComponentTypes;

macro_rules! define_pc_kind {
    ($ty:ident) => {
        #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
        pub struct $ty(usize);

        impl Add<usize> for $ty {
            type Output = $ty;
            fn add(self, other: usize) -> $ty {
                $ty(self.0.wrapping_add(other))
            }
        }
        impl Sub<usize> for $ty {
            type Output = $ty;
            fn sub(self, other: usize) -> $ty {
                $ty(self.0.wrapping_sub(other))
            }
        }

        impl $ty {
            /// Is the given PC within this range? Give the relative
            /// offset if so.
            pub fn offset_of(range: Range<$ty>, pc: usize) -> Option<usize> {
                if pc >= range.start.0 && pc < range.end.0 {
                    Some(pc.wrapping_sub(range.start.0))
                } else {
                    None
                }
            }

            /// Get the raw PC value.
            pub fn raw(&self) -> usize {
                self.0
            }
        }
    };
}

// An address in "engine code": the original (canonical) copy of code
// for a compiled module.
//
// See [`EngineCode`] for more details.
define_pc_kind!(EngineCodePC);

// An address in "store code": the copy of code used when executing
// instances of a module in a given store.
//
// May or may not be the same as the engine code address -- a store
// is allowed to make a private copy of engine code as its store
// code.
//
// See [`StoreCode`] for more details.
define_pc_kind!(StoreCodePC);

impl StoreCodePC {
    /// Construct a StoreCodePC for search purposes from a raw PC
    /// observed during execution.
    pub fn from_raw(pc: usize) -> StoreCodePC {
        StoreCodePC(pc)
    }
}

/// Metadata about, and original machine code for, a loaded compiled
/// artifact in memory which is ready for Wasmtime to execute.
///
/// This structure is used in both `Module` and `Component`. For components it's
/// notably shared amongst the core wasm modules within a component and the
/// component itself. For core wasm modules this is uniquely owned within a
/// `Module`.
///
/// The `EngineCode` is "static", like a module: there is one copy per
/// unit of code. Instantiation of a module containing an `EngineCode`
/// into a `Store` produces a `StoreCode`. The latter is the owner of
/// the actual machine code that runs. This machine code *may* be a
/// read-only-shared copy of the original, or may be a private copy
/// that we have patched. The latter is useful for some kinds of
/// debugging/instrumentation, which is always scoped per-Store.
///
/// The `EngineCode` does *not* expose its underlying `CodeMemory`, to
/// guard against the original-copy being used in an inappropriate
/// (store-specific) context. Instead, it has accessors that provide
/// the instance-agnostic metadata from the `CodeMemory`, and
/// instance-specific data and code pointers can be obtained from the
/// `StoreCode`.
pub struct EngineCode {
    /// Actual underlying code which is executable and contains other
    /// compiled information.
    ///
    /// Note the `Arc` here is used to share this with `CompiledModule` and the
    /// global module registry of traps. While probably not strictly necessary
    /// and could be avoided with some refactorings is a hopefully a relatively
    /// minor `Arc` for now.
    ///
    /// As noted above, this is the *original* copy of the code, and
    /// may be used directly, but may also be deep-cloned to a private
    /// copy in a `StoreCode`.
    original_code: Arc<CodeMemory>,

    /// Registered shared signature for the loaded object.
    ///
    /// Note that this type has a significant destructor which unregisters
    /// signatures within the `Engine` it was originally tied to, and this ends
    /// up corresponding to the lifetime of a `Component` or `Module`.
    signatures: TypeCollection,

    /// Type information for the loaded object.
    ///
    /// This is either a `ModuleTypes` or a `ComponentTypes` depending on the
    /// top-level creator of this code.
    types: Types,
}

impl EngineCode {
    pub fn new(mmap: Arc<CodeMemory>, signatures: TypeCollection, types: Types) -> EngineCode {
        // The corresponding unregister for this is below in `Drop for
        // EngineCode`.
        crate::module::register_code(&mmap, mmap.raw_addr_range());

        EngineCode {
            original_code: mmap,
            signatures,
            types,
        }
    }

    #[cfg(feature = "component-model")]
    pub fn types(&self) -> &Types {
        &self.types
    }

    pub fn module_types(&self) -> &ModuleTypes {
        self.types.module_types()
    }

    pub fn signatures(&self) -> &TypeCollection {
        &self.signatures
    }

    pub fn text_size(&self) -> usize {
        self.original_code.text().len()
    }

    /// Give the range of engine-code PCs in this code.
    pub fn text_range(&self) -> Range<EngineCodePC> {
        let raw = self.original_code.raw_addr_range();
        EngineCodePC(raw.start)..EngineCodePC(raw.end)
    }

    // For all accessors to code object sections below: we can use the
    // original (uncloned) code image for these: they are just slices
    // of bytes that we interpret independent of location.
    //
    // We hide the raw `CodeMemory` in `original_code` (*not* a public
    // field) because we do not want the EngineCode copy used
    // inadvertently for execution of Wasm functions.
    //
    // We thus *cannot* add an accessor below for anything that
    // actually interprets the location of the bytes as a code
    // pointer to a Wasm function.
    //
    // Note that Wasm-to-array trampolines, in contrast, are fair game
    // to execute directly from the EngineCode: these are not specific
    // to Wasm functions, but instead call builtins, and we never
    // patch trampolines in StoreCode, so we can freely mix in
    // EngineCode variants.

    /// Get the Wasm-to-array trampoline for the given raw range in
    /// the text segment.
    pub(crate) fn raw_wasm_to_array_trampoline_data(&self, range: Range<usize>) -> &[u8] {
        &self.original_code.text()[range]
    }

    /// Provide the address-map data for this EngineCode.
    pub fn address_map_data(&self) -> &[u8] {
        // We can use the original (uncloned) code image for this: it
        // is just a slice of bytes that we interpret independent of
        // location.
        self.original_code.address_map_data()
    }

    /// Provide the stack-map data for this EngineCode.
    pub fn stack_map_data(&self) -> &[u8] {
        // We can use the original (uncloned) code image for this: it
        // is just a slice of bytes that we interpret independent of
        // location.
        self.original_code.stack_map_data()
    }

    /// Returns the encoded exception-tables section to pass to
    /// `wasmtime_unwinder::ExceptionTable::parse`.
    pub fn exception_tables(&self) -> &[u8] {
        // We can use the original (uncloned) code image for this: it
        // is just a slice of bytes that we interpret independent of
        // location.
        self.original_code.exception_tables()
    }

    /// Returns the encoded frame-tables section to pass to
    /// `wasmtime_environ::FrameTable::parse`.
    pub fn frame_tables(&self) -> &[u8] {
        self.original_code.frame_tables()
    }

    /// Returns the data in the `ELF_NAME_DATA` section.
    #[inline]
    pub fn func_name_data(&self) -> &[u8] {
        self.original_code.func_name_data()
    }

    /// Returns the contents of the `ELF_WASMTIME_DWARF` section.
    #[inline]
    pub fn wasm_dwarf(&self) -> &[u8] {
        self.original_code.wasm_dwarf()
    }

    /// Returns the raw image as bytes (in our internal image format).
    pub fn image(&self) -> &[u8] {
        &self.original_code.mmap()[..]
    }

    pub fn text(&self) -> &[u8] {
        &self.original_code.text()
    }

    /// Returns the concatenated list of all data associated with this wasm
    /// module.
    ///
    /// This is used for initialization of memories and all data ranges stored
    /// in a `Module` are relative to the slice returned here.
    #[inline]
    pub fn wasm_data(&self) -> &[u8] {
        self.original_code.wasm_data()
    }

    pub(crate) fn module_memory_image_source(&self) -> &Arc<impl ModuleMemoryImageSource> {
        &self.original_code
    }
}

impl Drop for EngineCode {
    fn drop(&mut self) {
        crate::module::unregister_code(self.original_code.raw_addr_range());
    }
}

pub enum Types {
    Module(ModuleTypes),
    #[cfg(feature = "component-model")]
    Component(Arc<ComponentTypes>),
}

impl Types {
    fn module_types(&self) -> &ModuleTypes {
        match self {
            Types::Module(m) => m,
            #[cfg(feature = "component-model")]
            Types::Component(c) => c.module_types(),
        }
    }
}

impl From<ModuleTypes> for Types {
    fn from(types: ModuleTypes) -> Types {
        Types::Module(types)
    }
}

#[cfg(feature = "component-model")]
impl From<Arc<ComponentTypes>> for Types {
    fn from(types: Arc<ComponentTypes>) -> Types {
        Types::Component(types)
    }
}

/// A `Store`-local instance of code.
///
/// This type encapsulates executable code within the context of
/// instantiation in a single store. It may be an unmodified pointer
/// to the read-only original code, or it may be locally patched for
/// this store due to debugging or instrumentation settings.
///
/// Most things that the runtime will want to do with a module's image
/// will require the `EngineCode` -- all metadata lives there. The
/// `StoreCode` is solely responsible for the executable machine code.
///
/// This type is designed to be uniquely owned, unlike `EngineCode`
/// above. The runtime data structures will have scattered `Arc`s to
/// the `EngineCode` but only one
pub struct StoreCode(StoreCodeStorage);

enum StoreCodeStorage {
    Shared(Arc<CodeMemory>),
    /// Private copy of the given code memory.
    ///
    /// This is the only reference to this CodeMemory. The StoreCode
    /// is owned directly by the Store's ModuleRegistry.
    #[cfg(feature = "debug")]
    Private(Box<CodeMemory>),
}

impl StoreCode {
    /// Create a new StoreCode for a given Store from a given
    /// EngineCode, given the engine's settings (tunables).
    pub fn new(engine: &Engine, engine_code: &Arc<EngineCode>) -> Result<Self> {
        // Enabled guest-debugging causes us to allocate private
        // copies of code in every store, to allow individual enabling
        // of breakpoints (by code patching) independently in each
        // one.
        #[cfg(feature = "debug")]
        let code = if engine.tunables().debug_guest {
            // TODO(#12104): we should be able to clone only `.text`;
            // this clones the whole image.
            let mut private_copy = engine_code.original_code.deep_clone(engine)?;
            private_copy.publish()?;
            crate::module::register_code(&engine_code.original_code, private_copy.raw_addr_range());
            StoreCodeStorage::Private(Box::new(private_copy))
        } else {
            StoreCodeStorage::Shared(engine_code.original_code.clone())
        };

        #[cfg(not(feature = "debug"))]
        let code = StoreCodeStorage::Shared(engine_code.original_code.clone());
        // Avoid unused-variable warning in build without debugging
        // support.
        let _ = engine;

        Ok(StoreCode(code))
    }

    /// Provide the underlying CodeMemory.
    pub fn code_memory(&self) -> &CodeMemory {
        match &self.0 {
            StoreCodeStorage::Shared(m) => m,
            #[cfg(feature = "debug")]
            StoreCodeStorage::Private(m) => m,
        }
    }

    /// Provide a mutable reference to a CodeMemory that is privately
    /// owned only by this StoreCode.
    #[cfg(feature = "debug")]
    pub fn code_memory_mut(&mut self) -> Option<&mut CodeMemory> {
        match &mut self.0 {
            StoreCodeStorage::Shared(_) => None,
            StoreCodeStorage::Private(m) => Some(m),
        }
    }

    /// Provide the address range for this StoreCode.
    pub fn text_range(&self) -> Range<StoreCodePC> {
        let raw = self.code_memory().raw_addr_range();
        StoreCodePC(raw.start)..StoreCodePC(raw.end)
    }

    /// Provide the actual text segment for this StoreCode.
    pub fn text(&self) -> &[u8] {
        self.code_memory().text()
    }
}

impl Drop for StoreCode {
    fn drop(&mut self) {
        match &self.0 {
            StoreCodeStorage::Shared(_) => {
                // Drop impl for EngineCode will de-register (see
                // above).
            }
            #[cfg(feature = "debug")]
            StoreCodeStorage::Private(mem) => {
                crate::module::unregister_code(mem.raw_addr_range());
            }
        }
    }
}

/// A wrapper for a Module together with a StoreCode. Allows fetching
/// code pointers, ready to call.
pub struct ModuleWithCode<'a> {
    module: &'a Module,
    store_code: &'a StoreCode,
}

impl<'a> ModuleWithCode<'a> {
    /// Find the StoreCode in a given store for a module and wrap it
    /// up with that module, ready to compute code pointers.
    pub fn in_store(
        registry: &'a ModuleRegistry,
        module: &'a Module,
    ) -> Option<ModuleWithCode<'a>> {
        let store_code = registry.store_code(module.engine_code())?;
        Some(ModuleWithCode { module, store_code })
    }

    pub(crate) fn from_raw(module: &'a Module, store_code: &'a StoreCode) -> ModuleWithCode<'a> {
        ModuleWithCode { module, store_code }
    }

    /// Provide the Module wrapped in this tuple.
    pub fn module(&self) -> &'a Module {
        self.module
    }

    /// Provide the StoreCode wrapped in this tuple.
    pub fn store_code(&self) -> &'a StoreCode {
        self.store_code
    }

    /// Returns an iterator over all functions defined within this module with
    /// their index and their raw pointer.
    #[inline]
    pub fn finished_functions(
        &self,
    ) -> impl ExactSizeIterator<Item = (DefinedFuncIndex, &[u8])> + '_ {
        self.module
            .env_module()
            .defined_func_indices()
            .map(|i| (i, self.finished_function(i)))
    }

    /// Returns the slice in the text section of the function that
    /// `index` points to.
    #[inline]
    pub fn finished_function(&self, def_func_index: DefinedFuncIndex) -> &[u8] {
        let range = self
            .module
            .compiled_module()
            .finished_function_range(def_func_index);
        &self.store_code.text()[range]
    }

    /// Get the array-to-Wasm trampoline for the function `index`
    /// points to, as a slice of raw code that can be converted to a
    /// callable function pointer.
    ///
    /// If the function `index` points to does not escape, then `None` is
    /// returned.
    ///
    /// These trampolines are used for array callers (e.g. `Func::new`)
    /// calling Wasm callees.
    pub fn array_to_wasm_trampoline(&self, def_func_index: DefinedFuncIndex) -> Option<&[u8]> {
        let range = self
            .module
            .compiled_module()
            .array_to_wasm_trampoline_range(def_func_index)?;
        Some(&self.store_code.text()[range])
    }

    /// Get the text offset (relative PC) for a given absolute PC in
    /// this module.
    #[cfg(feature = "gc")]
    pub(crate) fn text_offset(&self, pc: usize) -> Option<u32> {
        StoreCodePC::offset_of(self.store_code.text_range(), pc)
            .map(|offset| u32::try_from(offset).expect("Module larger than 4GiB"))
    }

    /// Lookup the stack map at a program counter value.
    #[cfg(feature = "gc")]
    pub(crate) fn lookup_stack_map(&self, pc: usize) -> Option<wasmtime_environ::StackMap<'_>> {
        let text_offset = self.text_offset(pc)?;
        let info = self.module.engine_code().stack_map_data();
        wasmtime_environ::StackMap::lookup(text_offset, info)
    }
}