fix vec extend

This commit is contained in:
janis 2025-10-31 15:19:26 +01:00
parent 9b4d42ba3a
commit c7f026a678
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
4 changed files with 84 additions and 14 deletions

View file

@ -12,6 +12,7 @@ extern allocate
global vec_init
global vec_init_with
global vec_extend
global vec_push
global vec_pop
global vec_drop_last
@ -29,13 +30,15 @@ global vec_tests
;; Byte vector structure
;; struct Vec {
;; start-structs
;; struct BlobVec {
;; data: *mut u8,
;; len: usize,
;; capacity: usize,
;; item_size: usize,
;; drop: Option<fn(*mut u8)>,
;; cap: usize,
;; elem_size: usize,
;; drop: Option<extern "C" fn(*mut u8)>,
;; }
;; end-structs
;; size: 40 bytes
;; align: 8 bytes
@ -629,3 +632,49 @@ vec_insert_sorted:
add rsp, 0x18
pop rbp
ret
;; rdi: *Vec
;; rsi: *const u8
;; rdx: number of elements
;; define-fn: fn vec_extend(vec: *mut BlobVec, elements: *const u8, count: usize) -> ()
vec_extend:
push rbp
mov rbp, rsp
; bytes [24..32]
; count [16..24]
; elements [8..16]
; vec [0..8]
sub rsp, 32
mov [rsp], rdi ; vec
mov [rsp + 8], rsi ; elements
mov [rsp + 16], rdx ; count
mov rax, [rdi + 24] ; item_size
mul rdx ; count * item_size
mov [rsp + 24], rax ; bytes
mov rsi, [rsp + 16] ; count
add rsi, [rdi + 8] ; vec.len + count
call vec_try_grow
mov rdi, [rsp] ; vec
mov rsi, [rdi + 8] ; vec.len
mov rax, [rdi + 24] ; item_size
mul rsi ; vec.len * item_size
add rax, [rdi] ; vec.data + vec.len * item_size
mov rdi, rax ; dest
mov rsi, [rsp + 8] ; elements
mov rdx, [rsp + 24] ; bytes
call memcpy
mov rdi, [rsp] ; vec
mov rax, [rdi + 8] ; vec.len
add rax, [rsp + 16] ; vec.len + count
mov [rdi + 8], rax
add rsp, 32
pop rbp
ret

View file

@ -17,6 +17,8 @@ unsafe extern "C" {
pub unsafe fn ast_build_symtable(ast: *mut Ast, root_index: u64, symtable: *mut core::mem::MaybeUninit<SymbolTable>);
pub unsafe fn ast_walk_for_each(ast: *mut Ast, start_index: u64, ctx: *mut (), for_each: unsafe extern "C" fn(ctx: *mut (), *mut Ast, node_index: u64, scope: u64));
pub unsafe fn ast_resolve_var_refs(ast: *mut Ast, ctx: *mut SymbolTable, root_index: u64);
pub unsafe fn codegen_function(ast: *const Ast, func_idx: usize) -> ();
pub unsafe fn vec_extend(vec: *mut BlobVec, elements: *const u8, count: usize) -> ();
}
pub const SYM_KEY_SCOPE: u8 = 1;
@ -190,4 +192,14 @@ pub struct SymEntry {
pub extra: u64,
}
#[repr(C)]
#[derive(Debug)]
pub struct BlobVec {
pub data: *mut u8,
pub len: usize,
pub cap: usize,
pub elem_size: usize,
pub drop: Option<extern "C" fn(*mut u8)>,
}
use super::vec::Vec;

View file

@ -52,15 +52,7 @@ impl FFISlice {
}
}
#[repr(C)]
#[derive(Debug)]
pub struct BlobVec {
pub data: *mut u8,
pub len: usize,
pub cap: usize,
pub elem_size: usize,
pub drop: Option<extern "C" fn(*mut u8)>,
}
pub use defs::BlobVec;
impl Default for BlobVec {
fn default() -> Self {
@ -135,6 +127,18 @@ pub mod vec {
unsafe { core::slice::from_raw_parts_mut(self.vec.data as *mut T, self.vec.len) }
}
pub fn extend(&mut self, elements: Box<[T]>) {
unsafe {
let elements =
core::mem::transmute::<Box<[T]>, Box<[core::mem::ManuallyDrop<T>]>>(elements);
super::defs::vec_extend(
&mut self.vec,
elements.as_ptr() as *const u8,
elements.len(),
);
}
}
pub fn push(&mut self, value: T) {
let value = core::mem::ManuallyDrop::new(value);
unsafe {

View file

@ -106,6 +106,11 @@ fn main() {
assert_eq!(vec.as_slice(), &[20, 30, 35, 40, 50]);
let mut vec = Vec::<u32>::new_with(100);
vec.insert_sorted(50, cmp);
_ = vec.insert_sorted(50, cmp);
assert_eq!(vec.as_slice(), &[50]);
// vec extend
let elements = Box::new([1, 2, 3, 4, 5]);
vec.extend(elements);
assert_eq!(vec.as_slice(), &[50, 1, 2, 3, 4, 5]);
}