near_vm_compiler/
function.rs

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