summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaylan Kammer <taylan.kammer@gmail.com>2026-07-27 07:09:44 +0200
committerTaylan Kammer <taylan.kammer@gmail.com>2026-07-27 07:09:44 +0200
commita8d40828eb6c7ace41e7102ac18dc7b406b094eb (patch)
tree3434b5f8faadc55feb10ba3d01064430d9033cd1
parent86e77fc35b3a9146a31b872643a85f8f6a486a07 (diff)
Doc improvement.
-rw-r--r--doc/0/0-value.md41
1 files changed, 24 insertions, 17 deletions
diff --git a/doc/0/0-value.md b/doc/0/0-value.md
index f30735e..b84a528 100644
--- a/doc/0/0-value.md
+++ b/doc/0/0-value.md
@@ -105,9 +105,9 @@ highest bits, providing a payload value of 48 bits for each.
011 :: Immediate short string
- 100 :: Immediate small rational (sign bit 0)
+ 100 :: Immediate small rational
- 101 :: Immediate small rational (sign bit 1)
+ 101 :: Undefined
110 :: Undefined
@@ -126,11 +126,14 @@ highest bits, providing a payload value of 48 bits for each.
Forbidden Pattern #3, Positive cqNaN, is avoided thanks to the fact that some
bits of a list pointer are always set; see below.
-Zisp splits the native program heap provided by the platform into three regions
-of virtual memory: The list heap of 32 GiB, addressed in 64-bit (8-byte) units;
-the main heap of 32 GiB, also addressed in 64-bit units; and the 4 GiB heap for
-`istr` objects (interned strings) which is addressed in bytes. Each region can
-thus be addressed via 32-bit indices instead of larger direct pointers.
+Zisp divides platform-provided heap memory into regions that are addressed via
+32-bit indexes rather than direct pointers. Different pointer types may refer
+to different regions. For instance, a list pointer and a regular heap pointer
+may have the same index value, which does not mean that they point to the same
+real memory address. They may also be addressing their respective region with
+different unit sizes. For instance, `istr` (interned string) pointers may use
+byte-addressing, meaning the 32-bit index limits the `istr` heap to 4 GiB only,
+while list pointers use 64-bit (8-byte) addressing, allowing for a 32 GiB heap.
### List pointers
@@ -138,13 +141,13 @@ In Zisp, a list is a contiguous array of a fixed number of Values. To improve
memory density and cache locality, especially for the interpreter, lists of up
to 255 elements are allocated in tight blocks with little or no padding and no
metadata headers on the heap. Their length is therefore encoded directly with
-an 8-bit metadata field within the NaN-packed pointer.
+an 8-bit metadata field within the NaN-packed pointer itself.
The exact layout of the 48-bit payload is as follows:
The low 32 bits are an index into the list heap, while the higher 16 bits are
-divided into 8 high bits for the length, and 8 low bits for garbage collector
-or other internal metadata.
+divided into 8 high bits for the length, and 8 low bits for internal metadata
+such as for garbage collection.
The length bits cannot be zero. The empty list is represented by a different
bit pattern to provide a minor benefit during garbage collection: Zero-length
@@ -157,17 +160,20 @@ and the generic list API hides the difference.
### Heap pointers
-Regular heap objects are represented by this index type, which uses a 32-bit
+Regular heap objects are represented by this pointer type, which uses a 32-bit
index into the main heap, in the lower portion of the 48-bit payload.
Of the 16 high bits of the payload, the upper 8 are used to immediately encode
-the type of the heap object, and the remaining 8 are used for garbage collector
-metadata.
+the type of the heap object, and the remaining 8 are used for internal metadata
+such as for garbage collection.
This means our 64-bit Values can be checked against heap types by comparing the
24 high bits to a combined constant: the 16 high bits that indicate it's a main
heap index, plus 8 more bits encoding a specific heap type.
+Some heap types may actually reside in their own separate heap, meaning the
+32-bit index may refer to yet another memory region rather than the main heap.
+
### String pointers
An `istr` is a string of up to 255 arbitrary bytes, that is typically interned,
@@ -207,8 +213,9 @@ depend on the endianness of the platform.
### Small rationals
-We use a 49-bit space for small rational numbers, with a signed 25-bit two's
-complement integer numerator, and 24-bit unsigned integer denominator.
+We use a 48-bit space for small rational numbers, with a 32-bit signed two's
+complement integer numerator in the low 32 bits, and a 16-bit unsigned integer
+denominator in the high 16 bits of the payload.
### Runes & others
@@ -251,7 +258,7 @@ almost purely in-place mutations of the original source code tree.
010 :: Pointer to istr as constant
- 011 :: Short string as constant
+ 011 :: Immediate short string as constant
100 :: Pointer to opcodes in list heap
@@ -295,7 +302,7 @@ only of the above listed Value types.
Function arguments, and locally declared variables, reside in a "stack frame"
allocated for each call. Since a Value has a uniform 64-bit representation,
-the stack frame is simply an array.
+stack frames are simply Value arrays.
The low 16 bits of the payload are an index into the stack array; the other 32
bits are reserved for other purposes.