fix closure not decremented

This commit is contained in:
Folkert 2020-12-02 22:51:16 +01:00
parent 654342fb54
commit 0a8415b48e
3 changed files with 13 additions and 8 deletions

View file

@ -3,7 +3,7 @@ use crate::llvm::build::{
}; };
use crate::llvm::compare::build_eq; use crate::llvm::compare::build_eq;
use crate::llvm::convert::{basic_type_from_layout, collection, get_ptr_type}; use crate::llvm::convert::{basic_type_from_layout, collection, get_ptr_type};
use crate::llvm::refcounting::decrement_refcount_layout; use crate::llvm::refcounting::{decrement_refcount_layout, increment_refcount_layout};
use inkwell::builder::Builder; use inkwell::builder::Builder;
use inkwell::context::Context; use inkwell::context::Context;
use inkwell::types::{BasicTypeEnum, PointerType}; use inkwell::types::{BasicTypeEnum, PointerType};
@ -1370,6 +1370,7 @@ pub fn list_map<'a, 'ctx, 'env>(
let result = store_list(env, ret_list_ptr, len); let result = store_list(env, ret_list_ptr, len);
// decrement the input list (the function is a function pointer, and is never refcounted)
decrement_refcount_layout(env, parent, layout_ids, list, list_layout); decrement_refcount_layout(env, parent, layout_ids, list, list_layout);
result result
@ -1426,7 +1427,13 @@ pub fn list_map<'a, 'ctx, 'env>(
incrementing_elem_loop(builder, ctx, parent, list_ptr, len, "#index", list_loop); incrementing_elem_loop(builder, ctx, parent, list_ptr, len, "#index", list_loop);
store_list(env, ret_list_ptr, len) let result = store_list(env, ret_list_ptr, len);
// decrement the input list and input closure
decrement_refcount_layout(env, parent, layout_ids, list, list_layout);
decrement_refcount_layout(env, parent, layout_ids, func, func_layout);
result
}; };
if_list_is_not_empty(env, parent, non_empty_fn, list, list_layout, "List.map") if_list_is_not_empty(env, parent, non_empty_fn, list, list_layout, "List.map")

View file

@ -2,7 +2,7 @@ use crate::llvm::build::{
cast_basic_basic, cast_struct_struct, create_entry_block_alloca, set_name, Env, Scope, cast_basic_basic, cast_struct_struct, create_entry_block_alloca, set_name, Env, Scope,
FAST_CALL_CONV, LLVM_SADD_WITH_OVERFLOW_I64, FAST_CALL_CONV, LLVM_SADD_WITH_OVERFLOW_I64,
}; };
use crate::llvm::build_list::list_len; use crate::llvm::build_list::{incrementing_elem_loop, list_len, load_list};
use crate::llvm::convert::{basic_type_from_layout, block_of_memory, ptr_int}; use crate::llvm::convert::{basic_type_from_layout, block_of_memory, ptr_int};
use bumpalo::collections::Vec; use bumpalo::collections::Vec;
use inkwell::context::Context; use inkwell::context::Context;
@ -367,7 +367,6 @@ fn decrement_refcount_builtin<'a, 'ctx, 'env>(
List(memory_mode, element_layout) => { List(memory_mode, element_layout) => {
let wrapper_struct = value.into_struct_value(); let wrapper_struct = value.into_struct_value();
if element_layout.contains_refcounted() { if element_layout.contains_refcounted() {
use crate::llvm::build_list::{incrementing_elem_loop, load_list};
use inkwell::types::BasicType; use inkwell::types::BasicType;
let ptr_type = let ptr_type =
@ -451,7 +450,6 @@ fn increment_refcount_builtin<'a, 'ctx, 'env>(
List(memory_mode, element_layout) => { List(memory_mode, element_layout) => {
let wrapper_struct = value.into_struct_value(); let wrapper_struct = value.into_struct_value();
if element_layout.contains_refcounted() { if element_layout.contains_refcounted() {
use crate::llvm::build_list::{incrementing_elem_loop, load_list};
use inkwell::types::BasicType; use inkwell::types::BasicType;
let ptr_type = let ptr_type =

View file

@ -460,7 +460,7 @@ impl<'a> Layout<'a> {
pub fn is_refcounted(&self) -> bool { pub fn is_refcounted(&self) -> bool {
match self { match self {
Layout::Builtin(Builtin::List(_, _)) => true, Layout::Builtin(Builtin::List(MemoryMode::Refcounted, _)) => true,
Layout::Builtin(Builtin::Str) => true, Layout::Builtin(Builtin::Str) => true,
Layout::RecursiveUnion(_) => true, Layout::RecursiveUnion(_) => true,
Layout::RecursivePointer => true, Layout::RecursivePointer => true,
@ -477,12 +477,12 @@ impl<'a> Layout<'a> {
match self { match self {
Builtin(builtin) => builtin.is_refcounted(), Builtin(builtin) => builtin.is_refcounted(),
PhantomEmptyStruct => false, PhantomEmptyStruct => false,
Struct(fields) => fields.iter().any(|f| f.is_refcounted()), Struct(fields) => fields.iter().any(|f| f.contains_refcounted()),
Union(fields) => fields Union(fields) => fields
.iter() .iter()
.map(|ls| ls.iter()) .map(|ls| ls.iter())
.flatten() .flatten()
.any(|f| f.is_refcounted()), .any(|f| f.contains_refcounted()),
RecursiveUnion(_) => true, RecursiveUnion(_) => true,
Closure(_, closure_layout, _) => closure_layout.contains_refcounted(), Closure(_, closure_layout, _) => closure_layout.contains_refcounted(),
FunctionPointer(_, _) | RecursivePointer | Pointer(_) => false, FunctionPointer(_, _) | RecursivePointer | Pointer(_) => false,