from-scratch/stages/shared/vec.asm
2026-07-14 16:36:54 +02:00

78 lines
2 KiB
NASM

;; Vec / Dynamic Array Structure
extern heap_realloc
global vec_init
global vec_get_nth
global vec_reserve
struc Vec
.data resq 1 ; pointer to elements
.size resd 1 ; size in element count
.cap resd 1 ; cap in element count
.ele_size resd 1 ; size of each element in bytes
.ele_align resd 1 ; alignment of each element in bytes
endstruc
;; fn vec_init(vec: *mut Vec, ele_size: usize, ele_align: usize) -> *mut Vec
vec_init:
mov qword [rdi + Vec.data], 0
mov dword [rdi + Vec.size], 0
mov dword [rdi + Vec.cap], 0
mov dword [rdi + Vec.ele_size], esi
mov dword [rdi + Vec.ele_align], edx
mov rax, rdi
ret
;; fn vec_get_nth(vec: *const Vec, idx: usize) -> *const u8
vec_get_nth:
mov rax, rsi
mov ecx, dword [rdi + Vec.ele_size]
mul ecx
add rax, qword [rdi + Vec.data]
ret
;; reserve space for $rsi additional entries in vec $rdi.
;; fn vec_reserve(vec: *mut Vec, count: usize)
vec_reserve:
push rbp
mov rbp, rsp
sub rsp, 16
mov edx, dword [rdi + Vec.ele_size]
mov ecx, dword [rdi + Vec.ele_align]
mov dword [rsp], edx ; obj-size
mov dword [rsp + 4], ecx ; alignment
mov qword [rsp + 8], rdi ; table pointer
mov eax, dword [rdi + Vec.size]
add eax, esi
cmp eax, dword [rdi + Vec.cap]
jl .done
mov eax, esi
add eax, dword [rdi + Vec.size]
mov ecx, dword [rdi + Vec.cap]
mov edx, ecx
shl edx, 1
cmp eax, edx
cmovl eax, edx
; new cap
mul dword [rsp] ; obj-size
; old cap
xchg eax, ecx
mul dword [rsp] ; obj-size
mov rdi, qword [rdi + Vec.data] ; old pointer
mov esi, eax ; old size
mov edx, ecx ; new size
mov ecx, dword [rsp + 4] ; alignment
call heap_realloc
mov rdi, qword [rsp + 8] ; table pointer
mov qword [rdi + Vec.data], rax
.done:
add rsp, 16
pop rbp
ret