Skip to content

Commit

Permalink
Merge pull request #144 from m-ou-se/const_fn
Browse files Browse the repository at this point in the history
Add const_fn!{} macro to make functions const without duplication.
  • Loading branch information
phil-opp authored Apr 11, 2020
2 parents 1808cbe + d46d7c2 commit 2442fd9
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 179 deletions.
10 changes: 5 additions & 5 deletions src/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,31 +164,31 @@ impl VirtAddr {

/// Returns the 12-bit page offset of this virtual address.
#[inline]
pub fn page_offset(&self) -> PageOffset {
pub const fn page_offset(&self) -> PageOffset {
PageOffset::new_truncate(self.0 as u16)
}

/// Returns the 9-bit level 1 page table index.
#[inline]
pub fn p1_index(&self) -> PageTableIndex {
pub const fn p1_index(&self) -> PageTableIndex {
PageTableIndex::new_truncate((self.0 >> 12) as u16)
}

/// Returns the 9-bit level 2 page table index.
#[inline]
pub fn p2_index(&self) -> PageTableIndex {
pub const fn p2_index(&self) -> PageTableIndex {
PageTableIndex::new_truncate((self.0 >> 12 >> 9) as u16)
}

/// Returns the 9-bit level 3 page table index.
#[inline]
pub fn p3_index(&self) -> PageTableIndex {
pub const fn p3_index(&self) -> PageTableIndex {
PageTableIndex::new_truncate((self.0 >> 12 >> 9 >> 9) as u16)
}

/// Returns the 9-bit level 4 page table index.
#[inline]
pub fn p4_index(&self) -> PageTableIndex {
pub const fn p4_index(&self) -> PageTableIndex {
PageTableIndex::new_truncate((self.0 >> 12 >> 9 >> 9 >> 9) as u16)
}
}
Expand Down
66 changes: 21 additions & 45 deletions src/instructions/port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,21 +114,13 @@ pub struct Port<T: PortReadWrite> {
}

impl<T: PortRead> PortReadOnly<T> {
/// Creates a read only I/O port with the given port number.
#[cfg(feature = "const_fn")]
pub const fn new(port: u16) -> PortReadOnly<T> {
PortReadOnly {
port,
phantom: PhantomData,
}
}

/// Creates a read only I/O port with the given port number.
#[cfg(not(feature = "const_fn"))]
pub fn new(port: u16) -> PortReadOnly<T> {
PortReadOnly {
port,
phantom: PhantomData,
const_fn! {
/// Creates a read only I/O port with the given port number.
pub fn new(port: u16) -> PortReadOnly<T> {
PortReadOnly {
port,
phantom: PhantomData,
}
}
}

Expand All @@ -145,21 +137,13 @@ impl<T: PortRead> PortReadOnly<T> {
}

impl<T: PortWrite> PortWriteOnly<T> {
/// Creates a write only I/O port with the given port number.
#[cfg(feature = "const_fn")]
pub const fn new(port: u16) -> PortWriteOnly<T> {
PortWriteOnly {
port,
phantom: PhantomData,
}
}

/// Creates a write only I/O port with the given port number.
#[cfg(not(feature = "const_fn"))]
pub fn new(port: u16) -> PortWriteOnly<T> {
PortWriteOnly {
port,
phantom: PhantomData,
const_fn! {
/// Creates a write only I/O port with the given port number.
pub fn new(port: u16) -> PortWriteOnly<T> {
PortWriteOnly {
port,
phantom: PhantomData,
}
}
}

Expand All @@ -176,21 +160,13 @@ impl<T: PortWrite> PortWriteOnly<T> {
}

impl<T: PortReadWrite> Port<T> {
/// Creates an I/O port with the given port number.
#[cfg(feature = "const_fn")]
pub const fn new(port: u16) -> Port<T> {
Port {
port,
phantom: PhantomData,
}
}

/// Creates an I/O port with the given port number.
#[cfg(not(feature = "const_fn"))]
pub fn new(port: u16) -> Port<T> {
Port {
port,
phantom: PhantomData,
const_fn! {
/// Creates an I/O port with the given port number.
pub fn new(port: u16) -> Port<T> {
Port {
port,
phantom: PhantomData,
}
}
}

Expand Down
19 changes: 19 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@

pub use crate::addr::{align_down, align_up, PhysAddr, VirtAddr};

/// Makes a function const only when `feature = "const_fn"` is enabled.
///
/// This is needed for const functions with bounds on their generic parameters,
/// such as those in `Page` and `PhysFrame` and many more.
macro_rules! const_fn {
(
$(#[$attr:meta])*
pub $($fn:tt)*
) => {
$(#[$attr])*
#[cfg(feature = "const_fn")]
pub const $($fn)*

$(#[$attr])*
#[cfg(not(feature = "const_fn"))]
pub $($fn)*
}
}

#[cfg(not(feature = "inline_asm"))]
pub(crate) mod asm;

Expand Down
91 changes: 30 additions & 61 deletions src/structures/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,67 +370,36 @@ pub struct InterruptDescriptorTable {
}

impl InterruptDescriptorTable {
/// Creates a new IDT filled with non-present entries.
#[cfg(feature = "const_fn")]
pub const fn new() -> InterruptDescriptorTable {
InterruptDescriptorTable {
divide_error: Entry::missing(),
debug: Entry::missing(),
non_maskable_interrupt: Entry::missing(),
breakpoint: Entry::missing(),
overflow: Entry::missing(),
bound_range_exceeded: Entry::missing(),
invalid_opcode: Entry::missing(),
device_not_available: Entry::missing(),
double_fault: Entry::missing(),
coprocessor_segment_overrun: Entry::missing(),
invalid_tss: Entry::missing(),
segment_not_present: Entry::missing(),
stack_segment_fault: Entry::missing(),
general_protection_fault: Entry::missing(),
page_fault: Entry::missing(),
reserved_1: Entry::missing(),
x87_floating_point: Entry::missing(),
alignment_check: Entry::missing(),
machine_check: Entry::missing(),
simd_floating_point: Entry::missing(),
virtualization: Entry::missing(),
reserved_2: [Entry::missing(); 9],
security_exception: Entry::missing(),
reserved_3: Entry::missing(),
interrupts: [Entry::missing(); 256 - 32],
}
}

/// Creates a new IDT filled with non-present entries.
#[cfg(not(feature = "const_fn"))]
pub fn new() -> InterruptDescriptorTable {
InterruptDescriptorTable {
divide_error: Entry::missing(),
debug: Entry::missing(),
non_maskable_interrupt: Entry::missing(),
breakpoint: Entry::missing(),
overflow: Entry::missing(),
bound_range_exceeded: Entry::missing(),
invalid_opcode: Entry::missing(),
device_not_available: Entry::missing(),
double_fault: Entry::missing(),
coprocessor_segment_overrun: Entry::missing(),
invalid_tss: Entry::missing(),
segment_not_present: Entry::missing(),
stack_segment_fault: Entry::missing(),
general_protection_fault: Entry::missing(),
page_fault: Entry::missing(),
reserved_1: Entry::missing(),
x87_floating_point: Entry::missing(),
alignment_check: Entry::missing(),
machine_check: Entry::missing(),
simd_floating_point: Entry::missing(),
virtualization: Entry::missing(),
reserved_2: [Entry::missing(); 9],
security_exception: Entry::missing(),
reserved_3: Entry::missing(),
interrupts: [Entry::missing(); 256 - 32],
const_fn! {
/// Creates a new IDT filled with non-present entries.
pub fn new() -> InterruptDescriptorTable {
InterruptDescriptorTable {
divide_error: Entry::missing(),
debug: Entry::missing(),
non_maskable_interrupt: Entry::missing(),
breakpoint: Entry::missing(),
overflow: Entry::missing(),
bound_range_exceeded: Entry::missing(),
invalid_opcode: Entry::missing(),
device_not_available: Entry::missing(),
double_fault: Entry::missing(),
coprocessor_segment_overrun: Entry::missing(),
invalid_tss: Entry::missing(),
segment_not_present: Entry::missing(),
stack_segment_fault: Entry::missing(),
general_protection_fault: Entry::missing(),
page_fault: Entry::missing(),
reserved_1: Entry::missing(),
x87_floating_point: Entry::missing(),
alignment_check: Entry::missing(),
machine_check: Entry::missing(),
simd_floating_point: Entry::missing(),
virtualization: Entry::missing(),
reserved_2: [Entry::missing(); 9],
security_exception: Entry::missing(),
reserved_3: Entry::missing(),
interrupts: [Entry::missing(); 256 - 32],
}
}
}

Expand Down
44 changes: 26 additions & 18 deletions src/structures/paging/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,38 @@ impl<S: PageSize> PhysFrame<S> {
}
}

/// Returns the start address of the frame.
#[allow(clippy::trivially_copy_pass_by_ref)]
#[inline]
pub fn start_address(&self) -> PhysAddr {
self.start_address
const_fn! {
/// Returns the start address of the frame.
#[allow(clippy::trivially_copy_pass_by_ref)]
#[inline]
pub fn start_address(&self) -> PhysAddr {
self.start_address
}
}

/// Returns the size the frame (4KB, 2MB or 1GB).
#[allow(clippy::trivially_copy_pass_by_ref)]
#[inline]
pub fn size(&self) -> u64 {
S::SIZE
const_fn! {
/// Returns the size the frame (4KB, 2MB or 1GB).
#[allow(clippy::trivially_copy_pass_by_ref)]
#[inline]
pub fn size(&self) -> u64 {
S::SIZE
}
}

/// Returns a range of frames, exclusive `end`.
#[inline]
pub fn range(start: PhysFrame<S>, end: PhysFrame<S>) -> PhysFrameRange<S> {
PhysFrameRange { start, end }
const_fn! {
/// Returns a range of frames, exclusive `end`.
#[inline]
pub fn range(start: PhysFrame<S>, end: PhysFrame<S>) -> PhysFrameRange<S> {
PhysFrameRange { start, end }
}
}

/// Returns a range of frames, inclusive `end`.
#[inline]
pub fn range_inclusive(start: PhysFrame<S>, end: PhysFrame<S>) -> PhysFrameRangeInclusive<S> {
PhysFrameRangeInclusive { start, end }
const_fn! {
/// Returns a range of frames, inclusive `end`.
#[inline]
pub fn range_inclusive(start: PhysFrame<S>, end: PhysFrame<S>) -> PhysFrameRangeInclusive<S> {
PhysFrameRangeInclusive { start, end }
}
}
}

Expand Down
Loading

0 comments on commit 2442fd9

Please sign in to comment.