From c7f026a67857b11339033f8a21b160dcdbfaf377 Mon Sep 17 00:00:00 2001 From: janis Date: Fri, 31 Oct 2025 15:19:26 +0100 Subject: [PATCH] fix vec extend --- lang/src/vec.asm | 57 ++++++++++++++++++++++++++++++++++--- lang/tests/shared/defs.rs | 12 ++++++++ lang/tests/shared/shared.rs | 22 ++++++++------ lang/tests/vec.rs | 7 ++++- 4 files changed, 84 insertions(+), 14 deletions(-) diff --git a/lang/src/vec.asm b/lang/src/vec.asm index 96f4048..4a21e6c 100644 --- a/lang/src/vec.asm +++ b/lang/src/vec.asm @@ -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, +;; cap: usize, +;; elem_size: usize, +;; drop: Option, ;; } +;; 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 diff --git a/lang/tests/shared/defs.rs b/lang/tests/shared/defs.rs index e44c2c5..bddda5b 100644 --- a/lang/tests/shared/defs.rs +++ b/lang/tests/shared/defs.rs @@ -17,6 +17,8 @@ unsafe extern "C" { pub unsafe fn ast_build_symtable(ast: *mut Ast, root_index: u64, symtable: *mut core::mem::MaybeUninit); 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, +} + use super::vec::Vec; diff --git a/lang/tests/shared/shared.rs b/lang/tests/shared/shared.rs index 3e4510e..f0fd5a8 100644 --- a/lang/tests/shared/shared.rs +++ b/lang/tests/shared/shared.rs @@ -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, -} +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<[core::mem::ManuallyDrop]>>(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 { diff --git a/lang/tests/vec.rs b/lang/tests/vec.rs index 79ca9f2..0bf910a 100644 --- a/lang/tests/vec.rs +++ b/lang/tests/vec.rs @@ -106,6 +106,11 @@ fn main() { assert_eq!(vec.as_slice(), &[20, 30, 35, 40, 50]); let mut vec = Vec::::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]); }