pub enum Repr {
Unit,
Bool,
Int,
Float,
Duration,
Ref,
Addr,
Host,
Task,
Scope,
Tag,
}Expand description
The interpretation of one word.
The collector consults exactly one thing about a Repr: whether it is
Repr::Ref. Everything else is for the boundary, the verifier and the
printer, all of which run outside the dispatch loop.
Variants§
Unit
Nothing. The word is zero.
Unit is a value in Cove — fn f() {} answers one — so it takes a
slot rather than being absent, which keeps the slot numbering and the
calling convention free of a special case.
Bool
0 or 1.
Int
A two’s-complement i64.
Float
An IEEE-754 double, bit-cast into the word.
Bit-cast rather than converted: f64::to_bits round-trips every
value including the NaN payloads, and the word is never read as an
integer by anything that did not write it as one.
Duration
Nanoseconds, as an i64.
A separate Repr from Repr::Int although the bits are the same,
because the boundary has to know which one to materialise and asking
the slot is cheaper than carrying a second table.
Ref
The linear address of a heap object’s header, or 0 for none.
This is the only Repr the collector treats as a root. Heap
addresses start at STACK_WORDS, so 0 can never name an object and
is free to mean null — which is what a frame full of zeroes gives a
Ref slot that has not been written yet.
Addr
The linear address of one mutable word: a place.
Not a root. The object an interior address points into is kept alive
by the Ref slot the lowering holds it in, and the heap does not
move, so the address stays correct across a collection without the
collector knowing it exists.
Host
An index into the run’s host resource table.
A host resource is owned by the host, not by Cove, so it is not an object in the heap and not a root. The word names it; the host owns its lifetime.
Task
A task handle: one past an index into the task’s scheduler table, or
0 for none.
Not a root, and for the same reason Repr::Host is not: what the
word names is not storage this collector allocated. A task is a
thread, a cancellation flag and a place to put an answer, and none of
those is a Cove value. The answer is an object in the run’s heap,
and the table names its address — which makes the table a provider of
roots rather than a second place to keep a value, because nothing a
program can write down could be put in one.
One past the index, so that a slot a zeroed frame has not written
names no task. That is Repr::Host’s rule, kept because the reason
for it is the same one.
Scope
A task scope: one past an index into the task’s scheduler table, or
0 for none.
The other half of what Repr::Task names, under the same rules. A
scope owns the tasks spawned into it, which is what lets leaving one
wait for or cancel them, and it holds nothing else.
Neither of these two crosses a task boundary — the task-safety rule says so — so the table they index is the task’s own and never a second task’s. Two tasks cannot form one another’s handles, which is the same disjointness by construction that keeps two stack segments apart.
Tag
An enum’s case index: which case an enum value holds.
Physically an integer word and semantically not an integer. It is
produced by Inst::Tag, consumed by
Inst::Switch, copied and cleared like any
other word, and refused by arithmetic, ordering and integer equality —
which is the whole of why it is a Repr of its own rather than
Repr::Int with a comment.
Implementations§
Trait Implementations§
impl Copy for Repr
impl Eq for Repr
impl StructuralPartialEq for Repr
Auto Trait Implementations§
impl Freeze for Repr
impl RefUnwindSafe for Repr
impl Send for Repr
impl Sync for Repr
impl Unpin for Repr
impl UnsafeUnpin for Repr
impl UnwindSafe for Repr
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.