[−][src]Struct passerine::vm::tag::Tagged
Tagged
implements Nan-tagging around the Data
enum.
In essence, it's possible to exploit the representation of f64
NaNs
to store pointers to other datatypes.
When laid out, this is what the bit-level representation of a double-precision floating-point number looks like:
SExponent---QIMantissa------------------------------------------
PNaN--------11D-Payload-------------------------------------...T
Where S
is sign, Q
is quiet flag, I
is Intel’s "QNan Floating-Point Indefinite";
P
is pointer flag, D
is Data Tag (should always be 1), T
is Tag.
By exploiting this fact, assuming a 64-bit system,
each item on the stack only takes up a machine word.
This differs from having a stack of Box
'd Data
,
because small items, like booleans, stack frames, etc.
can be encoded directly into the tag
rather than having to follow a pointer.
It also keeps math fast for f64s, as a simple check and transmutation
is all that's needed to reinterpret the bits as a valid number.
NOTE: implementation modeled after:
- rpjohnst/dejavu,
- and the Optimization chapter from Crafting Interpreters.
Thank you!
Implementations
impl Tagged
[src]
pub fn new(data: Data) -> Tagged
[src]
Wraps Data
to create a new tagged pointer.
pub fn frame() -> Tagged
[src]
Creates a new stack frame.
pub fn not_init() -> Tagged
[src]
pub fn data(self) -> Data
[src]
Unwrapps a tagged number into the appropriate datatype, consuming the tagged number.
pub fn copy(&self) -> Data
[src]
Deeply copies some Tagged
data.
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for Tagged
impl Send for Tagged
impl Sync for Tagged
impl Unpin for Tagged
impl UnwindSafe for Tagged
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,