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}