unc_vm_compiler/
section.rs

1//! This module define the required structures to emit custom
2//! Sections in a `Compilation`.
3//!
4//! The functions that access a custom [`CustomSection`] would need
5//! to emit a custom relocation: `RelocationTarget::CustomSection`, so
6//! it can be patched later by the engine (native or JIT).
7
8use crate::lib::std::vec::Vec;
9use crate::Relocation;
10use unc_vm_types::entity::entity_impl;
11
12/// Index type of a Section defined inside a WebAssembly `Compilation`.
13#[derive(rkyv::Serialize, rkyv::Deserialize, rkyv::Archive)]
14#[archive_attr(derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug))]
15#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
16pub struct SectionIndex(u32);
17
18entity_impl!(SectionIndex);
19
20entity_impl!(ArchivedSectionIndex);
21
22/// Custom section Protection.
23///
24/// Determines how a custom section may be used.
25#[derive(rkyv::Serialize, rkyv::Deserialize, rkyv::Archive, Debug, Copy, Clone, PartialEq, Eq)]
26pub enum CustomSectionProtection {
27    /// A custom section with read permission.
28    Read,
29
30    /// A custom section with read and execute permissions.
31    ReadExecute,
32}
33
34/// A Section for a `Compilation`.
35///
36/// This is used so compilers can store arbitrary information
37/// in the emitted module.
38#[derive(rkyv::Serialize, rkyv::Deserialize, rkyv::Archive, Debug, Clone, PartialEq, Eq)]
39pub struct CustomSection {
40    /// Memory protection that applies to this section.
41    pub protection: CustomSectionProtection,
42
43    /// The bytes corresponding to this section.
44    ///
45    /// > Note: These bytes have to be at-least 8-byte aligned
46    /// > (the start of the memory pointer).
47    /// > We might need to create another field for alignment in case it's
48    /// > needed in the future.
49    pub bytes: SectionBody,
50
51    /// Relocations that apply to this custom section.
52    pub relocations: Vec<Relocation>,
53}
54
55/// See [`CustomSection`].
56///
57/// Note that this does not reference the relocation data.
58#[derive(Clone, Copy)]
59pub struct CustomSectionRef<'a> {
60    /// See [`CustomSection::protection`].
61    pub protection: CustomSectionProtection,
62
63    /// See [`CustomSection::bytes`].
64    pub bytes: &'a [u8],
65}
66
67impl<'a> From<&'a CustomSection> for CustomSectionRef<'a> {
68    fn from(section: &'a CustomSection) -> Self {
69        CustomSectionRef { protection: section.protection, bytes: section.bytes.as_slice() }
70    }
71}
72
73impl<'a> From<&'a ArchivedCustomSection> for CustomSectionRef<'a> {
74    fn from(section: &'a ArchivedCustomSection) -> Self {
75        CustomSectionRef {
76            protection: Result::<_, std::convert::Infallible>::unwrap(
77                rkyv::Deserialize::deserialize(&section.protection, &mut rkyv::Infallible),
78            ),
79            bytes: &section.bytes.0[..],
80        }
81    }
82}
83
84/// The bytes in the section.
85#[derive(
86    rkyv::Serialize, rkyv::Deserialize, rkyv::Archive, Debug, Clone, PartialEq, Eq, Default,
87)]
88pub struct SectionBody(Vec<u8>);
89
90impl SectionBody {
91    /// Create a new section body with the given contents.
92    pub fn new_with_vec(contents: Vec<u8>) -> Self {
93        Self(contents)
94    }
95
96    /// Returns a raw pointer to the section's buffer.
97    pub fn as_ptr(&self) -> *const u8 {
98        self.0.as_ptr()
99    }
100
101    /// Returns the length of this section in bytes.
102    pub fn len(&self) -> usize {
103        self.0.len()
104    }
105
106    /// Dereferences into the section's buffer.
107    pub fn as_slice(&self) -> &[u8] {
108        self.0.as_slice()
109    }
110
111    /// Returns whether or not the section body is empty.
112    pub fn is_empty(&self) -> bool {
113        self.0.is_empty()
114    }
115}