@@ -22,7 +22,7 @@ const ADDRESS_SPACE_SIZE: u64 = 0x1_0000_0000_0000;
22
22
/// between `u64` and `usize`.
23
23
///
24
24
/// On `x86_64`, only the 48 lower bits of a virtual address can be used. The top 16 bits need
25
- /// to be copies of bit 47, i.e. the most significant bit. Addresses that fulfil this criterium
25
+ /// to be copies of bit 47, i.e. the most significant bit. Addresses that fulfil this criterion
26
26
/// are called “canonical”. This type guarantees that it always represents a canonical address.
27
27
#[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
28
28
#[ repr( transparent) ]
@@ -62,39 +62,43 @@ impl core::fmt::Debug for VirtAddrNotValid {
62
62
impl VirtAddr {
63
63
/// Creates a new canonical virtual address.
64
64
///
65
- /// This function performs sign extension of bit 47 to make the address canonical.
65
+ /// The provided address should already be canonical. If you want to check
66
+ /// whether an address is canonical, use [`try_new`](Self::try_new).
66
67
///
67
68
/// ## Panics
68
69
///
69
- /// This function panics if the bits in the range 48 to 64 contain data (i.e. are not null and no sign extension).
70
- #[ inline]
71
- pub fn new ( addr : u64 ) -> VirtAddr {
72
- Self :: try_new ( addr) . expect (
73
- "address passed to VirtAddr::new must not contain any data \
74
- in bits 48 to 64",
75
- )
70
+ /// This function panics if the bits in the range 48 to 64 are invalid
71
+ /// (i.e. are not a proper sign extension of bit 47).
72
+ #[ inline]
73
+ pub const fn new ( addr : u64 ) -> VirtAddr {
74
+ // TODO: Replace with .ok().expect(msg) when that works on stable.
75
+ match Self :: try_new ( addr) {
76
+ Ok ( v) => v,
77
+ Err ( _) => panic ! ( "virtual address must be sign extended in bits 48 to 64" ) ,
78
+ }
76
79
}
77
80
78
81
/// Tries to create a new canonical virtual address.
79
82
///
80
- /// This function tries to performs sign
81
- /// extension of bit 47 to make the address canonical. It succeeds if bits 48 to 64 are
82
- /// either a correct sign extension (i.e. copies of bit 47) or all null. Else, an error
83
- /// is returned.
84
- #[ inline]
85
- pub fn try_new ( addr : u64 ) -> Result < VirtAddr , VirtAddrNotValid > {
86
- match addr. get_bits ( 47 ..64 ) {
87
- 0 | 0x1ffff => Ok ( VirtAddr ( addr) ) , // address is canonical
88
- 1 => Ok ( VirtAddr :: new_truncate ( addr) ) , // address needs sign extension
89
- _ => Err ( VirtAddrNotValid ( addr) ) ,
83
+ /// This function checks wether the given address is canonical
84
+ /// and returns an error otherwise. An address is canonical
85
+ /// if bits 48 to 64 are a correct sign
86
+ /// extension (i.e. copies of bit 47).
87
+ #[ inline]
88
+ pub const fn try_new ( addr : u64 ) -> Result < VirtAddr , VirtAddrNotValid > {
89
+ let v = Self :: new_truncate ( addr) ;
90
+ if v. 0 == addr {
91
+ Ok ( v)
92
+ } else {
93
+ Err ( VirtAddrNotValid ( addr) )
90
94
}
91
95
}
92
96
93
97
/// Creates a new canonical virtual address, throwing out bits 48..64.
94
98
///
95
- /// This function performs sign extension of bit 47 to make the address canonical, so
96
- /// bits 48 to 64 are overwritten . If you want to check that these bits contain no data,
97
- /// use `new` or `try_new`.
99
+ /// This function performs sign extension of bit 47 to make the address
100
+ /// canonical, overwriting bits 48 to 64. If you want to check whether an
101
+ /// address is canonical, use [ `new`](Self::new) or [ `try_new`](Self::try_new) .
98
102
#[ inline]
99
103
pub const fn new_truncate ( addr : u64 ) -> VirtAddr {
100
104
// By doing the right shift as a signed operation (on a i64), it will
@@ -125,11 +129,7 @@ impl VirtAddr {
125
129
}
126
130
127
131
/// Creates a virtual address from the given pointer
128
- // cfg(target_pointer_width = "32") is only here for backwards
129
- // compatibility: Earlier versions of this crate did not have any `cfg()`
130
- // on this function. At least for 32- and 64-bit we know the `as u64` cast
131
- // doesn't truncate.
132
- #[ cfg( any( target_pointer_width = "32" , target_pointer_width = "64" ) ) ]
132
+ #[ cfg( target_pointer_width = "64" ) ]
133
133
#[ inline]
134
134
pub fn from_ptr < T > ( ptr : * const T ) -> Self {
135
135
Self :: new ( ptr as u64 )
0 commit comments