mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
add List.getUnsafe
This commit is contained in:
parent
c47209c54a
commit
f8e12da809
3 changed files with 64 additions and 4 deletions
|
@ -897,6 +897,39 @@ impl<
|
||||||
fn build_list_len(&mut self, dst: &Symbol, list: &Symbol) {
|
fn build_list_len(&mut self, dst: &Symbol, list: &Symbol) {
|
||||||
self.storage_manager.list_len(&mut self.buf, dst, list);
|
self.storage_manager.list_len(&mut self.buf, dst, list);
|
||||||
}
|
}
|
||||||
|
fn build_list_get_unsafe(
|
||||||
|
&mut self,
|
||||||
|
dst: &Symbol,
|
||||||
|
list: &Symbol,
|
||||||
|
index: &Symbol,
|
||||||
|
ret_layout: &Layout<'a>,
|
||||||
|
) {
|
||||||
|
let (base_offset, _) = self.storage_manager.stack_offset_and_size(list);
|
||||||
|
let index_reg = self
|
||||||
|
.storage_manager
|
||||||
|
.load_to_general_reg(&mut self.buf, index);
|
||||||
|
let ret_stack_size = ret_layout.stack_size(self.storage_manager.target_info());
|
||||||
|
// TODO: This can be optimized with smarter instructions.
|
||||||
|
// Also can probably be moved into storage manager at least partly.
|
||||||
|
self.storage_manager.with_tmp_general_reg(
|
||||||
|
&mut self.buf,
|
||||||
|
|storage_manager, buf, list_ptr| {
|
||||||
|
ASM::mov_reg64_base32(buf, list_ptr, base_offset as i32);
|
||||||
|
storage_manager.with_tmp_general_reg(buf, |storage_manager, buf, tmp| {
|
||||||
|
ASM::mov_reg64_imm64(buf, tmp, ret_stack_size as i64);
|
||||||
|
ASM::imul_reg64_reg64_reg64(buf, tmp, tmp, index_reg);
|
||||||
|
ASM::add_reg64_reg64_reg64(buf, tmp, tmp, list_ptr);
|
||||||
|
match ret_layout {
|
||||||
|
single_register_integers!() if ret_stack_size == 8 => {
|
||||||
|
let dst_reg = storage_manager.claim_general_reg(buf, dst);
|
||||||
|
ASM::mov_reg64_mem64_offset32(buf, dst_reg, list_ptr, 0);
|
||||||
|
}
|
||||||
|
x => internal_error!("Loading list element with layout: {:?}", x),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn build_ptr_cast(&mut self, dst: &Symbol, src: &Symbol) {
|
fn build_ptr_cast(&mut self, dst: &Symbol, src: &Symbol) {
|
||||||
// We may not strictly need an instruction here.
|
// We may not strictly need an instruction here.
|
||||||
|
@ -1073,12 +1106,19 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! sign_extended_builtins {
|
macro_rules! sign_extended_int_builtins {
|
||||||
() => {
|
() => {
|
||||||
Builtin::Int(IntWidth::I8 | IntWidth::I16 | IntWidth::I32 | IntWidth::I64 | IntWidth::I128)
|
Builtin::Int(IntWidth::I8 | IntWidth::I16 | IntWidth::I32 | IntWidth::I64 | IntWidth::I128)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! zero_extended_int_builtins {
|
||||||
|
() => {
|
||||||
|
Builtin::Int(IntWidth::U8 | IntWidth::U16 | IntWidth::U32 | IntWidth::U64 | IntWidth::U128)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! single_register_int_builtins {
|
macro_rules! single_register_int_builtins {
|
||||||
() => {
|
() => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
generic64::{Assembler, CallConv, RegTrait},
|
generic64::{Assembler, CallConv, RegTrait},
|
||||||
sign_extended_builtins, single_register_floats, single_register_int_builtins,
|
sign_extended_int_builtins, single_register_floats, single_register_int_builtins,
|
||||||
single_register_integers, single_register_layouts, Env,
|
single_register_integers, single_register_layouts, Env,
|
||||||
};
|
};
|
||||||
use bumpalo::collections::Vec;
|
use bumpalo::collections::Vec;
|
||||||
|
@ -181,6 +181,10 @@ impl<
|
||||||
self.fn_call_stack_size = 0;
|
self.fn_call_stack_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn target_info(&self) -> TargetInfo {
|
||||||
|
self.target_info
|
||||||
|
}
|
||||||
|
|
||||||
pub fn stack_size(&self) -> u32 {
|
pub fn stack_size(&self) -> u32 {
|
||||||
self.stack_size
|
self.stack_size
|
||||||
}
|
}
|
||||||
|
@ -551,7 +555,7 @@ impl<
|
||||||
size,
|
size,
|
||||||
sign_extend: matches!(
|
sign_extend: matches!(
|
||||||
layout,
|
layout,
|
||||||
Layout::Builtin(sign_extended_builtins!())
|
Layout::Builtin(sign_extended_int_builtins!())
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -598,7 +602,7 @@ impl<
|
||||||
Stack(ReferencedPrimitive {
|
Stack(ReferencedPrimitive {
|
||||||
base_offset: union_offset + id_offset as i32,
|
base_offset: union_offset + id_offset as i32,
|
||||||
size,
|
size,
|
||||||
sign_extend: matches!(id_builtin, sign_extended_builtins!()),
|
sign_extend: matches!(id_builtin, sign_extended_int_builtins!()),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -558,6 +558,14 @@ trait Backend<'a> {
|
||||||
);
|
);
|
||||||
self.build_list_len(sym, &args[0])
|
self.build_list_len(sym, &args[0])
|
||||||
}
|
}
|
||||||
|
LowLevel::ListGetUnsafe => {
|
||||||
|
debug_assert_eq!(
|
||||||
|
2,
|
||||||
|
args.len(),
|
||||||
|
"ListLen: expected to have exactly two arguments"
|
||||||
|
);
|
||||||
|
self.build_list_get_unsafe(sym, &args[0], &args[1], ret_layout)
|
||||||
|
}
|
||||||
LowLevel::ListSet => self.build_fn_call(
|
LowLevel::ListSet => self.build_fn_call(
|
||||||
sym,
|
sym,
|
||||||
bitcode::LIST_SET.to_string(),
|
bitcode::LIST_SET.to_string(),
|
||||||
|
@ -703,6 +711,14 @@ trait Backend<'a> {
|
||||||
/// build_list_len returns the length of a list.
|
/// build_list_len returns the length of a list.
|
||||||
fn build_list_len(&mut self, dst: &Symbol, list: &Symbol);
|
fn build_list_len(&mut self, dst: &Symbol, list: &Symbol);
|
||||||
|
|
||||||
|
/// build_list_get_unsafe loads the element from the list at the index.
|
||||||
|
fn build_list_get_unsafe(
|
||||||
|
&mut self,
|
||||||
|
dst: &Symbol,
|
||||||
|
list: &Symbol,
|
||||||
|
index: &Symbol,
|
||||||
|
ret_layout: &Layout<'a>,
|
||||||
|
);
|
||||||
/// build_refcount_getptr loads the pointer to the reference count of src into dst.
|
/// build_refcount_getptr loads the pointer to the reference count of src into dst.
|
||||||
fn build_ptr_cast(&mut self, dst: &Symbol, src: &Symbol);
|
fn build_ptr_cast(&mut self, dst: &Symbol, src: &Symbol);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue