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    option::ArchivedOption, Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize,
23};
24#[cfg(feature = "enable-serde")]
25use serde::{Deserialize, Serialize};
26use wasmer_types::{
27    entity::PrimaryMap, FunctionIndex, LocalFunctionIndex, SignatureIndex, TrapInformation,
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<&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<&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<&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
117/// The compiled functions map (index in the Wasm -> function)
118pub type Functions = PrimaryMap<LocalFunctionIndex, CompiledFunction>;
119
120/// The custom sections for a Compilation.
121pub type CustomSections = PrimaryMap<SectionIndex, CustomSection>;
122
123/// The unwinding information for this Compilation.
124///
125/// It is used for retrieving the unwind information once an exception
126/// happens.
127/// In the future this structure may also hold other information useful
128/// for debugging.
129#[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))]
130#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
131#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, PartialEq, Eq, Clone, Default)]
132#[rkyv(derive(Debug), compare(PartialEq))]
133pub struct UnwindInfo {
134    /// The section index in the [`Compilation`] that corresponds to the exception frames.
135    /// [Learn
136    /// more](https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html).
137    pub eh_frame: Option<SectionIndex>,
138    pub compact_unwind: Option<SectionIndex>,
139}
140
141impl UnwindInfo {
142    /// Creates a `Dwarf` struct with the corresponding indices for its sections
143    pub fn new(eh_frame: SectionIndex) -> Self {
144        Self {
145            eh_frame: Some(eh_frame),
146            compact_unwind: None,
147        }
148    }
149
150    pub fn new_cu(compact_unwind: SectionIndex) -> Self {
151        Self {
152            eh_frame: None,
153            compact_unwind: Some(compact_unwind),
154        }
155    }
156}
157
158/// The GOT - Global Offset Table - for this Compilation.
159///
160/// The GOT is but a list of pointers to objects (functions, data, sections..); in our context the
161/// GOT is represented simply as a custom section.
162#[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))]
163#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
164#[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, PartialEq, Eq, Clone, Default)]
165#[rkyv(derive(Debug))]
166pub struct GOT {
167    /// The section index in the [`Compilation`] that corresponds to the GOT.
168    pub index: Option<SectionIndex>,
169}
170
171impl GOT {
172    pub fn empty() -> Self {
173        Self { index: None }
174    }
175}
176/// The result of compiling a WebAssembly module's functions.
177#[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))]
178#[derive(Debug, PartialEq, Eq)]
179pub struct Compilation {
180    /// Compiled code for the function bodies.
181    pub functions: Functions,
182
183    /// Custom sections for the module.
184    /// It will hold the data, for example, for constants used in a
185    /// function, global variables, rodata_64, hot/cold function partitioning, ...
186    pub custom_sections: CustomSections,
187
188    /// Trampolines to call a function defined locally in the wasm via a
189    /// provided `Vec` of values.
190    ///
191    /// This allows us to call easily Wasm functions, such as:
192    ///
193    /// ```ignore
194    /// let func = instance.exports.get_function("my_func");
195    /// func.call(&[Value::I32(1)]);
196    /// ```
197    pub function_call_trampolines: PrimaryMap<SignatureIndex, FunctionBody>,
198
199    /// Trampolines to call a dynamic function defined in
200    /// a host, from a Wasm module.
201    ///
202    /// This allows us to create dynamic Wasm functions, such as:
203    ///
204    /// ```ignore
205    /// fn my_func(values: &[Val]) -> Result<Vec<Val>, RuntimeError> {
206    ///     // do something
207    /// }
208    ///
209    /// let my_func_type = FunctionType::new(vec![Type::I32], vec![Type::I32]);
210    /// let imports = imports!{
211    ///     "namespace" => {
212    ///         "my_func" => Function::new(&store, my_func_type, my_func),
213    ///     }
214    /// }
215    /// ```
216    ///
217    /// Note: Dynamic function trampolines are only compiled for imported function types.
218    pub dynamic_function_trampolines: PrimaryMap<FunctionIndex, FunctionBody>,
219
220    /// Section ids corresponding to the unwind information.
221    pub unwind_info: UnwindInfo,
222
223    /// A reference to the [`GOT`] instance for the compilation.
224    pub got: GOT,
225}