Skip to content

Commit

Permalink
Update documentation per #147
Browse files Browse the repository at this point in the history
  • Loading branch information
myrrlyn committed Dec 21, 2021
1 parent 570d613 commit 9574c04
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 1 deletion.
22 changes: 22 additions & 0 deletions doc/access/BitAccess.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,28 @@ traits, but it is a crate-internal item and is not part of the public API. Its
blanket implementation for `<R: Radium>` prevents any other implementations from
being written.

## Implementation and Safety Notes

This trait is automatically implemented for all types that implement `Radium`,
and relies exclusively on `Radium`’s API and implementations for its work. In
particular, `Radium` has no functions which operate on **pointers**: it
exclusively operates on memory through **references**. Since references must
always refer to initialized memory, `BitAccess` and, by extension, all APIs in
`bitvec` that touch memory, cannot be used to operate on uninitialized memory in
any way.

While you may *create* a `bitvec` pointer object that targets uninitialized
memory, you may not *dereference* it until the targeted memory has been wholly
initialized with integer values.

This restriction cannot be loosened without stable access to pointer-based
atomic intrinsics in the Rust standard library and corresponding updates to the
`Radium` trait.

Do not attempt to access uninitialized memory through `bitvec`. Doing so will
cause `bitvec` to produce references to uninitialized memory, which is undefined
behavior.

[`Radium`]: radium::Radium
[`index`]: crate::index
[`radium`]: radium
Expand Down
16 changes: 15 additions & 1 deletion doc/ptr/BitPtr.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ crate-internal space optimizations.

- `M`: Marks whether the pointer has mutability permissions to the referent
memory. Only `Mut` pointers can be used to create `&mut` references.
- `O`: The ordering of bits within a memory element.
- `T`: A memory type used to select both the register width and the bus behavior
when performing memory accesses.
- `O`: The ordering of bits within a memory element.

## Usage

Expand All @@ -45,3 +45,17 @@ directly dereferenced, as it is not a pointer; it can only be transformed back
into higher referential types, or used in functions that accept it.

These pointers can never be null or misaligned.

## Safety

Rust and LLVM **do not** have a concept of bit-level initialization yet.
Furthermore, the underlying foundational code that this type uses to manipulate
individual bits in memory relies on construction of **shared references** to
memory, which means that unlike standard pointers, the `T` element to which
`BitPtr` values point must always be **already initialized** in your program
context.

`bitvec` is not able to detect or enforce this requirement, and is currently not
able to avoid it. See [`BitAccess`] for more information.

[`BitAccess`]: crate::access::BitAccess
18 changes: 18 additions & 0 deletions doc/vec/BitVec.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,29 @@ useful for client crates to propagate. `<usize, Lsb0>` is fastest; `<u8, Msb0>`
matches what most debugger views of memory will print, and the rest are
documented in the guide.

## Safety

Unlike the other data structures in this crate, `BitVec` is uniquely able to
hold uninitialized memory and produce pointers into it. As described in the
[`BitAccess`] documentation, this crate is categorically unable to operate on
uninitialized memory in any way. In particular, you may not allocate a buffer
using [`with_capacity()`], then use [`.as_mut_bitptr()`] to create a pointer
used to write into the uninitialized buffer.

You must always initialize the buffer contents of a `BitVec` before attempting
to view its contents. You can accomplish this through safe APIs such as
`.push()`, `.extend()`, or `.reserve()`. These are all guaranteed to safely
initialize the memory elements underlying the `BitVec` buffer without incurring
undefined behavior in their operation.

[book]: https://bitvecto-rs.github.io/bitvec/type-parameters.html
[`BitAccess`]: crate::access::BitAccess
[`BitArray`]: crate::array::BitArray
[`BitField`]: crate::field::BitField
[`BitSlice`]: crate::slice::BitSlice
[`bitvec!`]: macro@crate::bitvec
[`std::vector<bool>`]: https://en.cppreference.com/w/cpp/container/vector_bool
[`.as_mut_bitptr()`]: crate::slice::BitSlice::as_mut_bitptr
[`.get_mut()`]: crate::slice::BitSlice::get_mut
[`.set()`]: crate::slice::BitSlice::set
[`::with_capacity()`]: Self::with_capacity
30 changes: 30 additions & 0 deletions src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,36 @@ where
unsafe { slice::from_raw_parts_mut(data, len) }
}

/// Creates an unsafe shared bit-pointer to the start of the buffer.
///
/// ## Original
///
/// [`Vec::as_ptr`](alloc::vec::Vec::as_ptr)
///
/// ## Safety
///
/// You must initialize the contents of the underlying buffer before
/// accessing memory through this pointer. See the `BitPtr` documentation
/// for more details.
pub fn as_bitptr(&self) -> BitPtr<Const, T, O> {
self.bitspan.to_bitptr().to_const()
}

/// Creates an unsafe writable bit-pointer to the start of the buffer.
///
/// ## Original
///
/// [`Vec::as_mut_ptr`](alloc::vec::Vec::as_mut_ptr)
///
/// ## Safety
///
/// You must initialize the contents of the underlying buffer before
/// accessing memory through this pointer. See the `BitPtr` documentation
/// for more details.
pub fn as_mut_bitptr(&mut self) -> BitPtr<Mut, T, O> {
self.bitspan.to_bitptr()
}

/// Converts a bit-vector into a boxed bit-slice.
///
/// This may cause a reällocation to drop any excess capacity.
Expand Down

0 comments on commit 9574c04

Please sign in to comment.