osom_encoders_x86_64/models/
encoded_instruction.rs

1use osom_encoders_common::FixedBuffer;
2
3/// Represents a binary encoded X64 instruction.
4///
5/// It is guaranteed to be of size 16. First 15 bytes
6/// takes the instruction itself, while last byte is its length.
7/// Note that X64 instruction's length is at most 15.
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9#[repr(transparent)]
10#[must_use]
11pub struct EncodedX86_64Instruction {
12    value: FixedBuffer<15>,
13}
14
15impl EncodedX86_64Instruction {
16    pub const MAX_SIZE: usize = 15;
17
18    /// Creates a new `EncodedInstruction` with all values set to 0.
19    ///
20    /// # Safety
21    ///
22    /// This function is unsafe because it crates an invalid instruction.
23    #[inline(always)]
24    pub(crate) const unsafe fn new() -> Self {
25        Self {
26            value: FixedBuffer::new(),
27        }
28    }
29
30    /// Creates a new `EncodedInstruction` from an array of `N` bytes.
31    /// Equivalent to [`EncodedInstruction::new`] followed by
32    /// [`EncodedInstruction::push_array`].
33    ///
34    /// # Safety
35    ///
36    /// This function is unsafe because it doesn't check whether
37    /// the underlying buffer has enough space to fit the array.
38    /// It is up to the caller to ensure that.
39    #[inline(always)]
40    pub(crate) const unsafe fn from_array<const N: usize>(array: [u8; N]) -> Self {
41        Self {
42            value: unsafe { FixedBuffer::from_array(array) },
43        }
44    }
45
46    /// Pushes an array of `N` bytes to the instruction.
47    ///
48    /// # Safety
49    ///
50    /// This function is unsafe because it doesn't check whether
51    /// the underlying buffer has enough space to fit the array.
52    /// It is up to the caller to ensure that.
53    #[inline(always)]
54    pub(crate) const unsafe fn push_array<const N: usize>(&mut self, array: [u8; N]) {
55        unsafe { self.value.push_array(array) };
56    }
57
58    /// Pushes slice to the instruction.
59    ///
60    /// # Safety
61    ///
62    /// This function is unsafe because it doesn't check whether
63    /// the underlying buffer has enough space to fit the slice.
64    /// It is up to the caller to ensure that.
65    #[inline(always)]
66    pub(crate) const unsafe fn push_slice(&mut self, slice: &[u8]) {
67        unsafe { self.value.push_slice(slice) };
68    }
69
70    #[inline(always)]
71    #[must_use]
72    pub const fn as_slice(&self) -> &[u8] {
73        self.value.as_slice()
74    }
75}