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}