mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
recursive refcount on lists
This commit is contained in:
parent
cd5e2b6817
commit
f492800a28
2 changed files with 80 additions and 16 deletions
|
@ -1570,6 +1570,26 @@ pub fn list_is_not_empty<'ctx>(env: &Env<'_, 'ctx, '_>, len: IntValue<'ctx>) ->
|
|||
)
|
||||
}
|
||||
|
||||
pub fn load_list<'ctx>(
|
||||
builder: &Builder<'ctx>,
|
||||
wrapper_struct: StructValue<'ctx>,
|
||||
ptr_type: PointerType<'ctx>,
|
||||
) -> (IntValue<'ctx>, PointerValue<'ctx>) {
|
||||
let ptr_as_int = builder
|
||||
.build_extract_value(wrapper_struct, Builtin::WRAPPER_PTR, "read_list_ptr")
|
||||
.unwrap()
|
||||
.into_int_value();
|
||||
|
||||
let ptr = builder.build_int_to_ptr(ptr_as_int, ptr_type, "list_cast_ptr");
|
||||
|
||||
let length = builder
|
||||
.build_extract_value(wrapper_struct, Builtin::WRAPPER_LEN, "list_len")
|
||||
.unwrap()
|
||||
.into_int_value();
|
||||
|
||||
(length, ptr)
|
||||
}
|
||||
|
||||
pub fn load_list_ptr<'ctx>(
|
||||
builder: &Builder<'ctx>,
|
||||
wrapper_struct: StructValue<'ctx>,
|
||||
|
|
|
@ -100,7 +100,7 @@ pub fn decrement_refcount_layout<'a, 'ctx, 'env>(
|
|||
#[inline(always)]
|
||||
fn decrement_refcount_builtin<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
_parent: FunctionValue<'ctx>,
|
||||
parent: FunctionValue<'ctx>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
value: BasicValueEnum<'ctx>,
|
||||
layout: &Layout<'a>,
|
||||
|
@ -109,14 +109,37 @@ fn decrement_refcount_builtin<'a, 'ctx, 'env>(
|
|||
use Builtin::*;
|
||||
|
||||
match builtin {
|
||||
List(MemoryMode::Refcounted, element_layout) => {
|
||||
List(memory_mode, element_layout) => {
|
||||
let wrapper_struct = value.into_struct_value();
|
||||
if element_layout.contains_refcounted() {
|
||||
// TODO decrement all values
|
||||
use crate::llvm::build_list::{incrementing_elem_loop, load_list};
|
||||
use inkwell::types::BasicType;
|
||||
|
||||
let ptr_type =
|
||||
basic_type_from_layout(env.arena, env.context, element_layout, env.ptr_bytes)
|
||||
.ptr_type(AddressSpace::Generic);
|
||||
|
||||
let (len, ptr) = load_list(env.builder, wrapper_struct, ptr_type);
|
||||
|
||||
let loop_fn = |_index, element| {
|
||||
decrement_refcount_layout(env, parent, layout_ids, element, element_layout);
|
||||
};
|
||||
|
||||
incrementing_elem_loop(
|
||||
env.builder,
|
||||
env.context,
|
||||
parent,
|
||||
ptr,
|
||||
len,
|
||||
"dec_index",
|
||||
loop_fn,
|
||||
);
|
||||
}
|
||||
build_dec_list(env, layout_ids, layout, value.into_struct_value());
|
||||
}
|
||||
List(MemoryMode::Unique, _element_layout) => {
|
||||
// do nothing
|
||||
|
||||
if let MemoryMode::Refcounted = memory_mode {
|
||||
build_inc_list(env, layout_ids, layout, wrapper_struct);
|
||||
}
|
||||
build_dec_list(env, layout_ids, layout, wrapper_struct);
|
||||
}
|
||||
Set(element_layout) => {
|
||||
if element_layout.contains_refcounted() {
|
||||
|
@ -158,7 +181,7 @@ pub fn increment_refcount_layout<'a, 'ctx, 'env>(
|
|||
#[inline(always)]
|
||||
fn increment_refcount_builtin<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
_parent: FunctionValue<'ctx>,
|
||||
parent: FunctionValue<'ctx>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
value: BasicValueEnum<'ctx>,
|
||||
layout: &Layout<'a>,
|
||||
|
@ -167,15 +190,36 @@ fn increment_refcount_builtin<'a, 'ctx, 'env>(
|
|||
use Builtin::*;
|
||||
|
||||
match builtin {
|
||||
List(MemoryMode::Refcounted, element_layout) => {
|
||||
if element_layout.contains_refcounted() {
|
||||
// TODO decrement all values
|
||||
}
|
||||
List(memory_mode, element_layout) => {
|
||||
let wrapper_struct = value.into_struct_value();
|
||||
build_inc_list(env, layout_ids, layout, wrapper_struct);
|
||||
}
|
||||
List(MemoryMode::Unique, _element_layout) => {
|
||||
// do nothing
|
||||
if element_layout.contains_refcounted() {
|
||||
use crate::llvm::build_list::{incrementing_elem_loop, load_list};
|
||||
use inkwell::types::BasicType;
|
||||
|
||||
let ptr_type =
|
||||
basic_type_from_layout(env.arena, env.context, element_layout, env.ptr_bytes)
|
||||
.ptr_type(AddressSpace::Generic);
|
||||
|
||||
let (len, ptr) = load_list(env.builder, wrapper_struct, ptr_type);
|
||||
|
||||
let loop_fn = |_index, element| {
|
||||
increment_refcount_layout(env, parent, layout_ids, element, element_layout);
|
||||
};
|
||||
|
||||
incrementing_elem_loop(
|
||||
env.builder,
|
||||
env.context,
|
||||
parent,
|
||||
ptr,
|
||||
len,
|
||||
"inc_index",
|
||||
loop_fn,
|
||||
);
|
||||
}
|
||||
|
||||
if let MemoryMode::Refcounted = memory_mode {
|
||||
build_inc_list(env, layout_ids, layout, wrapper_struct);
|
||||
}
|
||||
}
|
||||
Set(element_layout) => {
|
||||
if element_layout.contains_refcounted() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue