fix vec extend
This commit is contained in:
parent
9b4d42ba3a
commit
c7f026a678
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue