Skip to content

Commit 31c7f98

Browse files
committed
Slightly clarify memory model description re: dependent pairs.
1 parent c0fa128 commit 31c7f98

File tree

1 file changed

+16
-15
lines changed

1 file changed

+16
-15
lines changed

src/lib/Imp.hs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,21 +1601,22 @@ written into the destination supplied by the caller.
16011601
Now back to the important exception, dependent pairs. When we have a dependent
16021602
pair, like `(n:Nat &> Fin n => Float)`, we don't know the size of the `Fin n =>
16031603
Float` table because the `n` is given by the *value* of the (first element of
1604-
the) pair. We use these to encode dynamically-sized lists. We handle this case
1605-
by pretending that we can have an array of arbitrary-sized boxes. The
1606-
implementation is just an array of pointers. But these pointers behave quite
1607-
differently from either the pointers that point to standard buffers or the
1608-
pointers used as views of those buffers. We think of them as an implementation
1609-
detail modeling the interface of an array with variable-sized elements, stored
1610-
*as values* in the array. In particular, the buffer exclusively owns the memory
1611-
backing its boxes. When we free the buffer, we free its boxes. When we write to
1612-
a buffer at an index, allocate fresh memory for the new box and free the old box
1613-
(unless it's null, as for an uninitialized buffer). We can still take read-only
1614-
views of the data in the boxes, but only if we know the buffer itself is
1615-
immutable/frozen, because otherwise the box memory might be freed when it's
1616-
overwritten by another value, which could happen before exiting the scope (in
1617-
that sense it's no different from taking a slice of a buffer to represent a
1618-
subarray).
1604+
the) pair. We use these to encode dynamically-sized lists.
1605+
1606+
We handle having an array of these by pretending that we can have an array of
1607+
arbitrary-sized boxes. The implementation is just an array of pointers. But
1608+
these pointers behave quite differently from either the pointers that point to
1609+
standard buffers or the pointers used as views of those buffers. We think of
1610+
them as an implementation detail modeling the interface of an array with
1611+
variable-sized elements, stored *as values* in the array. In particular, the
1612+
outer buffer exclusively owns the memory backing its boxes. When we free the
1613+
buffer, we free its boxes. When we write to a buffer at an index, allocate fresh
1614+
memory for the new box and free the old box (unless it's null, as for an
1615+
uninitialized buffer). We can still take read-only views of the data in the
1616+
boxes, but only if we know the buffer itself is immutable/frozen, because
1617+
otherwise the box memory might be freed when it's overwritten by another value,
1618+
which could happen before exiting the scope (in that sense it's no different
1619+
from taking a slice of a buffer to represent a subarray).
16191620
16201621
Separate from this memory system, we have user-facing references, `Ref h a`,
16211622
from the `State` effect. The memory for these is managed by a separate system,

0 commit comments

Comments
 (0)