Download Game! Currently 84 players and visitors. Last logged in:PanthosSolvikToabesCaitline

Blitzer's Blog >> 71849

Back to blogs index
Posted: 29 Aug 2026 22:43 [ permalink ]
This is a massive win. Seeing that terminal output confirms the foundation is
structurally sound. The intrusive linked list operating over a flat Int32Array
guarantees we are ready for the x86 C-port when the time comes.
You have successfully completed Milestone 1.2.
Before you build Milestone 1.3 (String Allocation), we need to formally
specify the architecture of the Data Arena and how these Handle IDs interact
with the Tagged Pointers from Milestone 1.1.
Here is the architectural specification for integrating Strings into your
Ledger.
1. The Tagged Pointer Integration
Right now, your GHL returns a raw Handle ID (e.g., 0, 1, 2).
The VM execution core (Registers and Shadow Stack) must never see this raw ID.
They only see Tagged Pointers.
When the host returns a String Handle to the VM, it must shift the ID and
append the Type Tag (Tag 2 for Strings):
const TAG_STRING = 2;
let handle_id = 0; 
let vm_tagged_pointer = (handle_id << 3) | TAG_STRING; // Results in 0x02

When the VM calls SYS_STR_CONCAT and passes two tagged pointers in R1 and R2,
the Host must untag them before querying the GHL:
let handle_id = vm_tagged_pointer >>> 3;

2. The Data Arena (String Storage)
The GHL only stores metadata (24-byte nodes). Where do the actual string
characters live?
We must allocate a second flat memory block: the Data Arena.
 * In JS: A Uint8Array (e.g., 1MB or 10MB).
 * In C/x86: A raw malloc or memory-mapped page.
We treat strings purely as UTF-8 byte sequences, not native JS string objects.
This guarantees 1:1 isomorphism with how the C-kernel will read strings.
The Data Arena Allocation Pointer:
You will need a global variable (e.g., dataArenaOffset = 0). Every time a
string is allocated, it copies the bytes to this offset, and then increments
the offset by payloadSize.
3. Specification for SYS_STR_ALLOC
When the JS Compiler parses "Hello", it triggers this host routine.
 * Convert the native string "Hello" into a UTF-8 byte array.
 * Copy those bytes into the Uint8Array (Data Arena) at dataArenaOffset.
 * Request a new node from the GHL (allocHandle()).
 * Set the GHL Node fields:
   * refCount = 1
   * typeTag = 2
   * payloadSize = 5 (bytes)
   * dataOffset = dataArenaOffset
 * Increment dataArenaOffset += 5.
 * Return the Tagged Pointer to the VM.
4. Specification for SYS_STR_CONCAT
When LPC executes str1 + str2, it calls this routine with two Tagged Pointers.
 * Untag both pointers to get handle_A and handle_B.
 * Look up payloadSize and dataOffset for both in the GHL.
 * Allocate space in the Data Arena for size_A + size_B.
 * Copy bytes from Arena[offset_A] and Arena[offset_B] into the new Arena
space.
 * Allocate a new GHL node for the combined string.
 * Return the new Tagged Pointer.
Note: In this MVP iteration, we won't build a complex Data Arena garbage
collector (compaction). Just let dataArenaOffset grow infinitely for now. We
can build memory compaction later once the object model is proven.
The Goal for Your Next Dev-Session
In your dev-environment, your objective is to write the DataArena integration
and these two routines.
Prove it works by writing a JS test that:
 * Allocates "Hello " (Handle 0)
 * Allocates "HAUKI" (Handle 1)
 * Concatenates them into "Hello HAUKI" (Handle 2)
 * Reads Handle 2 from the Uint8Array and decodes it back to a JS string to
verify.