1.6 Memory Layout
Overview
udewy uses a simple, uniform memory layout. All values are 64-bit integers. Complex data structures are built using pointers and manual offset calculations.
Strings and Based Strings
Ordinary strings and based strings share the same layout in static memory:
┌──────────────────────┬────────────────┐
│ Byte length (8 bytes)│ Data (N bytes) │
└──────────────────────┴────────────────┘
- Length prefix: 8 bytes containing the byte count
- Data: exactly the ordinary string's decoded source bytes or the based string's MSB-first wire-order bytes
The expression holds a pointer to the start of the data (after the length). Access the byte length at ptr - 8:
let packet:int = 0x"01 02 ff"
let len:int = __load__(packet - 8) # 3
let first:int = __load_u8__(packet) # 1
let second:int = __load_u8__(packet + 1) # 2
Static vs Dynamic Data
Ordinary and based string literals are stored in static memory (the data section). Their storage may be shared by multiple uses and persists across calls, so literals should not be used as mutable working buffers.
let process = ():>void => {
let local_buf:int = __alloca__(256) # fresh for this call
let shared_buf:int = __static_alloca__(64) # one zero-initialized static buffer
# write through __store_u8__, __store_u64__, etc.
return void
}
Use __alloca__(size) for a fresh function-local mutable buffer, __static_alloca__(size) for a shared zero-initialized mutable buffer, or an allocator appropriate to the target for other lifetimes.
Simulating Structs
udewy doesn't have built-in structs. Use offset constants:
const PERSON_NAME:int = 0
const PERSON_AGE:int = 8
const PERSON_HEIGHT:int = 16
const PERSON_SIZE:int = 24
let person:int = alloc(PERSON_SIZE)
__store__(name_ptr person + PERSON_NAME)
__store__(25 person + PERSON_AGE)
__store__(180 person + PERSON_HEIGHT)
let age:int = __load__(person + PERSON_AGE)