wasmer_types/compilation/
function.rs

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