Memory Model ============ BearVM exposes two heap allocation strategies directly in the IR: manual allocation and arena allocation. Manual Allocation ----------------- ``alloc`` allocates memory on the heap. The argument is either a byte size or a struct type name:: %buf = alloc 16 %p = alloc Person Allocated memory is zero-initialised. The caller is responsible for freeing it with ``free``:: free %buf free %p Failing to call ``free`` leaks the memory. Using a pointer after freeing it is undefined behaviour. Working with Heap-Allocated Structs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To write to a heap-allocated struct, get a reference to the field with ``get_field_ref``, then use ``store``:: struct Person { age: int score: int } @main { %p = alloc Person %age_ref = get_field_ref %p, age store %age_ref, 42 %age_val = load %age_ref call puts(%age_val) free %p ret 0 } A struct can also be initialised in one step using a struct literal with ``store``:: %p_ptr = alloc Person store %p_ptr, { name: "Alice", age: 25 } Working with Arrays ~~~~~~~~~~~~~~~~~~~ Arrays are allocated with ``alloc_array``. Elements are accessed by index using ``get_index_ref``:: %arr = alloc_array int, 5 %i = const 0 ; write: store each index with its own value %elem_ptr = get_index_ref %arr, %i store %elem_ptr, %i ; read %val = load %elem_ptr free %arr Accessing an index outside the allocated length raises ``IndexOutOfBounds``. Arena Allocation ---------------- An arena groups allocations together so they can all be freed in one operation. This is useful when a set of allocations share the same lifetime. Create an arena with ``arena_create``, allocate from it with ``arena_alloc``, and release everything at once with ``arena_destroy``:: @test_arena { %arena = arena_create %a = arena_alloc %arena, 64 %b = arena_alloc %arena, 128 %c = arena_alloc %arena, 32 arena_destroy %arena ret 0 } Individual arena allocations cannot be freed. All memory belonging to an arena is released when ``arena_destroy`` is called. Using an invalid arena ID raises ``InvalidArena``. Choosing Between Manual and Arena Allocation -------------------------------------------- Use manual allocation when individual objects have independent lifetimes and need to be freed separately. Use arena allocation when a group of objects all become unreachable at the same point. A single ``arena_destroy`` is cheaper and less error-prone than calling ``free`` on each individual allocation.