wasmer_compiler/types/
function.rs

1/*
2 * ! Remove me once rkyv generates doc-comments for fields or generates an #[allow(missing_docs)]
3 * on their own.
4 */
5#![allow(missing_docs)]
6// This file contains code from external sources.
7// Attributions: https://github.com/wasmerio/wasmer/blob/main/docs/ATTRIBUTIONS.md
8
9//! A `Compilation` contains the compiled function bodies for a WebAssembly
10//! module (`CompiledFunction`).
11
12use super::{
13    address_map::FunctionAddressMap,
14    relocation::Relocation,
15    section::{CustomSection, SectionIndex},
16    unwind::{
17        ArchivedCompiledFunctionUnwindInfo, CompiledFunctionUnwindInfo,
18        CompiledFunctionUnwindInfoLike,
19    },
20};
21use rkyv::{
22    Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize, option::ArchivedOption,
23};
24#[cfg(feature = "enable-serde")]
25use serde::{Deserialize, Serialize};
26use wasmer_types::{
27    FunctionIndex, LocalFunctionIndex, SignatureIndex, TrapInformation, entity::PrimaryMap,
28};
29
30/// The frame info for a Compiled function.
31///
32/// This structure is only used for reconstructing
33/// the frame information after a `Trap`.
34#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
35#[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))]
36#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq, Default)]
37#[rkyv(derive(Debug))]
38pub struct CompiledFunctionFrameInfo {
39    /// The traps (in the function body).
40    ///
41    /// Code offsets of the traps MUST be in ascending order.
42    pub traps: Vec<TrapInformation>,
43
44    /// The address map.
45    pub address_map: FunctionAddressMap,
46}
47
48/// The function body.
49#[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))]
50#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
51#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)]
52#[rkyv(derive(Debug))]
53pub struct FunctionBody {
54    /// The function body bytes.
55    #[cfg_attr(feature = "enable-serde", serde(with = "serde_bytes"))]
56    pub body: Vec<u8>,
57
58    /// The function unwind info
59    pub unwind_info: Option<CompiledFunctionUnwindInfo>,
60}
61
62/// Any struct that acts like a `FunctionBody`.
63#[allow(missing_docs)]
64pub trait FunctionBodyLike<'a> {
65    type UnwindInfo: CompiledFunctionUnwindInfoLike<'a>;
66
67    fn body(&'a self) -> &'a [u8];
68    fn unwind_info(&'a self) -> Option<&'a Self::UnwindInfo>;
69}
70
71impl<'a> FunctionBodyLike<'a> for FunctionBody {
72    type UnwindInfo = CompiledFunctionUnwindInfo;
73
74    fn body(&'a self) -> &'a [u8] {
75        self.body.as_ref()
76    }
77
78    fn unwind_info(&'a self) -> Option<&'a Self::UnwindInfo> {
79        self.unwind_info.as_ref()
80    }
81}
82
83impl<'a> FunctionBodyLike<'a> for ArchivedFunctionBody {
84    type UnwindInfo = ArchivedCompiledFunctionUnwindInfo;
85
86    fn body(&'a self) -> &'a [u8] {
87        self.body.as_ref()
88    }
89
90    fn unwind_info(&'a self) -> Option<&'a Self::UnwindInfo> {
91        match self.unwind_info {
92            ArchivedOption::Some(ref x) => Some(x),
93            ArchivedOption::None => None,
94        }
95    }
96}
97
98/// The result of compiling a WebAssembly function.
99///
100/// This structure only have the compiled information data
101/// (function bytecode body, relocations, traps, jump tables
102/// and unwind information).
103#[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))]
104#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)]
105#[rkyv(derive(Debug))]
106pub struct CompiledFunction {
107    /// The function body.
108    pub body: FunctionBody,
109
110    /// The relocations (in the body)
111    pub relocations: Vec<Relocation>,
112
113    /// The frame information.
114    pub frame_info: CompiledFunctionFrameInfo,
115
116    /// The maximum stack allocation directly connected to the function itself
117    /// if tracked (does not include any potential function calls).
118    pub maximum_stack_usage: Option<usize>,
119}
120
121/// The compiled functions map (index in the Wasm -> function)
122pub type Functions = PrimaryMap<LocalFunctionIndex, CompiledFunction>;
123
124/// The custom sections for a Compilation.
125pub type CustomSections = PrimaryMap<SectionIndex, CustomSection>;
126
127/// The unwinding information for this Compilation.
128///
129/// It is used for retrieving the unwind information once an exception
130/// happens.
131/// In the future this structure may also hold other information useful
132/// for debugging.
133#[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))]
134#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
135#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, PartialEq, Eq, Clone, Default)]
136#[rkyv(derive(Debug), compare(PartialEq))]
137pub struct UnwindInfo {
138    /// The section index in the [`Compilation`] that corresponds to the exception frames.
139    /// [Learn
140    /// more](https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html).
141    pub eh_frame: Option<SectionIndex>,
142    pub compact_unwind: Option<SectionIndex>,
143}
144
145impl UnwindInfo {
146    /// Creates a `Dwarf` struct with the corresponding indices for its sections
147    pub fn new(eh_frame: SectionIndex) -> Self {
148        Self {
149            eh_frame: Some(eh_frame),
150            compact_unwind: None,
151        }
152    }
153
154    pub fn new_cu(compact_unwind: SectionIndex) -> Self {
155        Self {
156            eh_frame: None,
157            compact_unwind: Some(compact_unwind),
158        }
159    }
160}
161
162/// The GOT - Global Offset Table - for this Compilation.
163///
164/// The GOT is but a list of pointers to objects (functions, data, sections..); in our context the
165/// GOT is represented simply as a custom section.
166#[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))]
167#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
168#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, PartialEq, Eq, Clone, Default)]
169#[rkyv(derive(Debug))]
170pub struct GOT {
171    /// The section index in the [`Compilation`] that corresponds to the GOT.
172    pub index: Option<SectionIndex>,
173}
174
175impl GOT {
176    pub fn empty() -> Self {
177        Self { index: None }
178    }
179}
180/// The result of compiling a WebAssembly module's functions.
181#[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))]
182#[derive(Debug, PartialEq, Eq)]
183pub struct Compilation {
184    /// Compiled code for the function bodies.
185    pub functions: Functions,
186
187    /// Custom sections for the module.
188    /// It will hold the data, for example, for constants used in a
189    /// function, global variables, rodata_64, hot/cold function partitioning, ...
190    pub custom_sections: CustomSections,
191
192    /// Trampolines to call a function defined locally in the wasm via a
193    /// provided `Vec` of values.
194    ///
195    /// This allows us to call easily Wasm functions, such as:
196    ///
197    /// ```ignore
198    /// let func = instance.exports.get_function("my_func");
199    /// func.call(&[Value::I32(1)]);
200    /// ```
201    pub function_call_trampolines: PrimaryMap<SignatureIndex, FunctionBody>,
202
203    /// Trampolines to call a dynamic function defined in
204    /// a host, from a Wasm module.
205    ///
206    /// This allows us to create dynamic Wasm functions, such as:
207    ///
208    /// ```ignore
209    /// fn my_func(values: &[Val]) -> Result<Vec<Val>, RuntimeError> {
210    ///     // do something
211    /// }
212    ///
213    /// let my_func_type = FunctionType::new(vec![Type::I32], vec![Type::I32]);
214    /// let imports = imports!{
215    ///     "namespace" => {
216    ///         "my_func" => Function::new(&store, my_func_type, my_func),
217    ///     }
218    /// }
219    /// ```
220    ///
221    /// Note: Dynamic function trampolines are only compiled for imported function types.
222    pub dynamic_function_trampolines: PrimaryMap<FunctionIndex, FunctionBody>,
223
224    /// Section ids corresponding to the unwind information.
225    pub unwind_info: UnwindInfo,
226
227    /// A reference to the [`GOT`] instance for the compilation.
228    pub got: GOT,
229}