make closure layout more robust

This commit is contained in:
Folkert 2020-10-17 01:48:55 +02:00
parent 70a53bd544
commit 8b490b6221
5 changed files with 141 additions and 51 deletions

View file

@ -52,6 +52,7 @@ fn basic_type_from_function_layout<'ctx>(
arena: &Bump,
context: &'ctx Context,
args: &[Layout<'_>],
closure_type: Option<BasicTypeEnum<'ctx>>,
ret_layout: &Layout<'_>,
ptr_bytes: u32,
) -> BasicTypeEnum<'ctx> {
@ -64,6 +65,10 @@ fn basic_type_from_function_layout<'ctx>(
));
}
if let Some(closure) = closure_type {
arg_basic_types.push(closure);
}
let fn_type = get_fn_type(&ret_type, arg_basic_types.into_bump_slice());
let ptr_type = fn_type.ptr_type(AddressSpace::Generic);
@ -103,19 +108,27 @@ pub fn basic_type_from_layout<'ctx>(
match layout {
FunctionPointer(args, ret_layout) => {
basic_type_from_function_layout(arena, context, args, ret_layout, ptr_bytes)
basic_type_from_function_layout(arena, context, args, None, ret_layout, ptr_bytes)
}
Closure(args, closure_layout, ret_layout) => {
let args = {
let mut temp = Vec::from_iter_in(args.iter().cloned(), arena);
temp.push(Layout::Struct(closure_layout));
temp.into_bump_slice()
};
// let closure_data = block_of_memory(
// context,
// // &closure_layout.into_block_of_memory_layout(),
// &closure_layout.into_layout(),
// ptr_bytes,
// );
let function_pointer =
basic_type_from_function_layout(arena, context, args, ret_layout, ptr_bytes);
let closure_data =
basic_type_from_layout(arena, context, &closure_layout.into_layout(), ptr_bytes);
let closure_data = basic_type_from_record(arena, context, closure_layout, ptr_bytes);
let function_pointer = basic_type_from_function_layout(
arena,
context,
args,
Some(closure_data),
ret_layout,
ptr_bytes,
);
context
.struct_type(&[function_pointer, closure_data], false)

View file

@ -64,7 +64,7 @@ pub fn decrement_refcount_layout<'a, 'ctx, 'env>(
decrement_refcount_builtin(env, parent, layout_ids, value, layout, builtin)
}
Closure(_, closure_layout, _) => {
if closure_layout.iter().any(|f| f.contains_refcounted()) {
if closure_layout.contains_refcounted() {
let wrapper_struct = value.into_struct_value();
let field_ptr = env
@ -72,7 +72,13 @@ pub fn decrement_refcount_layout<'a, 'ctx, 'env>(
.build_extract_value(wrapper_struct, 1, "decrement_closure_data")
.unwrap();
decrement_refcount_struct(env, parent, layout_ids, field_ptr, closure_layout)
decrement_refcount_layout(
env,
parent,
layout_ids,
field_ptr,
&closure_layout.into_layout(),
)
}
}
Struct(layouts) => {