store list in a shorter way

This commit is contained in:
Folkert 2022-07-14 00:26:46 +02:00
parent b7d78d9237
commit 2fe590abf4
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
4 changed files with 41 additions and 50 deletions

View file

@ -2412,7 +2412,7 @@ fn list_literal<'a, 'ctx, 'env>(
.build_in_bounds_gep(global, &[zero, offset], "first_element_pointer")
};
super::build_list::store_list(env, ptr, list_length_intval)
super::build_list::store_list(env, ptr, list_length_intval).into()
} else {
// some of our elements are non-constant, so we must allocate space on the heap
let ptr = allocate_list(env, element_layout, list_length_intval);
@ -2436,7 +2436,7 @@ fn list_literal<'a, 'ctx, 'env>(
builder.build_store(elem_ptr, val);
}
super::build_list::store_list(env, ptr, list_length_intval)
super::build_list::store_list(env, ptr, list_length_intval).into()
}
} else {
let ptr = allocate_list(env, element_layout, list_length_intval);
@ -2455,7 +2455,7 @@ fn list_literal<'a, 'ctx, 'env>(
store_roc_value(env, *element_layout, elem_ptr, val);
}
super::build_list::store_list(env, ptr, list_length_intval)
super::build_list::store_list(env, ptr, list_length_intval).into()
}
}

View file

@ -15,7 +15,10 @@ use roc_builtins::bitcode;
use roc_module::symbol::Symbol;
use roc_mono::layout::{Builtin, Layout, LayoutIds};
use super::build::{create_entry_block_alloca, load_roc_value, load_symbol, store_roc_value};
use super::build::{
create_entry_block_alloca, load_roc_value, load_symbol, store_roc_value, struct_from_fields,
};
use super::convert::zig_list_type;
pub fn list_symbol_to_c_abi<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
@ -28,7 +31,7 @@ pub fn list_symbol_to_c_abi<'a, 'ctx, 'env>(
.and_then(|b| b.get_parent())
.unwrap();
let list_type = super::convert::zig_list_type(env);
let list_type = zig_list_type(env);
let list_alloca = create_entry_block_alloca(env, parent, list_type.into(), "list_alloca");
let list = load_symbol(scope, &symbol);
@ -319,21 +322,28 @@ pub fn list_replace_unsafe<'a, 'ctx, 'env>(
// Load the element and returned list into a struct.
let old_element = env.builder.build_load(element_ptr, "load_element");
let result = env
.context
.struct_type(
&[super::convert::zig_list_type(env).into(), element_type],
false,
)
.const_zero();
// the list has the same alignment as a usize / ptr. The element comes first in the struct if
// its alignment is bigger than that of a list.
let element_align = element_layout.alignment_bytes(env.target_info);
let element_first = element_align > env.target_info.ptr_width() as u32;
let fields = if element_first {
[element_type, zig_list_type(env).into()]
} else {
[zig_list_type(env).into(), element_type]
};
let result = env.context.struct_type(&fields, false).const_zero();
let (list_index, element_index) = if element_first { (1, 0) } else { (0, 1) };
let result = env
.builder
.build_insert_value(result, new_list, 0, "insert_list")
.build_insert_value(result, new_list, list_index, "insert_list")
.unwrap();
env.builder
.build_insert_value(result, old_element, 1, "insert_value")
.build_insert_value(result, old_element, element_index, "insert_value")
.unwrap()
.into_struct_value()
.into()
@ -757,7 +767,7 @@ where
}
pub fn empty_polymorphic_list<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValueEnum<'ctx> {
let struct_type = super::convert::zig_list_type(env);
let struct_type = zig_list_type(env);
// The pointer should be null (aka zero) and the length should be zero,
// so the whole struct should be a const_zero
@ -816,40 +826,19 @@ pub fn store_list<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
pointer_to_first_element: PointerValue<'ctx>,
len: IntValue<'ctx>,
) -> BasicValueEnum<'ctx> {
let builder = env.builder;
) -> StructValue<'ctx> {
let ptr = pass_as_opaque(env, pointer_to_first_element);
let cap = len;
let struct_type = super::convert::zig_list_type(env);
// Store the pointer
let mut struct_val = builder
.build_insert_value(
struct_type.get_undef(),
pass_as_opaque(env, pointer_to_first_element),
Builtin::WRAPPER_PTR,
"insert_ptr_store_list",
)
.unwrap();
// Store the length
struct_val = builder
.build_insert_value(struct_val, len, Builtin::WRAPPER_LEN, "insert_len")
.unwrap();
// Store the capacity
struct_val = builder
.build_insert_value(
struct_val,
len,
Builtin::WRAPPER_CAPACITY,
"insert_capacity",
)
.unwrap();
builder.build_bitcast(
struct_val.into_struct_value(),
super::convert::zig_list_type(env),
"cast_collection",
struct_from_fields(
env,
zig_list_type(env),
[
(Builtin::WRAPPER_PTR as usize, ptr),
(Builtin::WRAPPER_LEN as usize, len.into()),
(Builtin::WRAPPER_CAPACITY as usize, cap.into()),
]
.into_iter(),
)
}

View file

@ -1,4 +1,4 @@
use crate::llvm::bitcode::{call_bitcode_fn, call_str_bitcode_fn};
use crate::llvm::bitcode::call_str_bitcode_fn;
use crate::llvm::build::{Env, Scope};
use inkwell::builder::Builder;
use inkwell::values::{BasicValueEnum, IntValue, PointerValue, StructValue};
@ -8,6 +8,7 @@ use roc_module::symbol::Symbol;
use roc_mono::layout::{Builtin, Layout};
use roc_target::PtrWidth;
use super::bitcode::call_bitcode_fn;
use super::build::{create_entry_block_alloca, load_symbol};
pub static CHAR_LAYOUT: Layout = Layout::u8();
@ -137,7 +138,7 @@ pub fn dec_to_str<'a, 'ctx, 'env>(
}
/// Str.equal : Str, Str -> Bool
pub fn str_equal<'a, 'ctx, 'env>(
pub(crate) fn str_equal<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
value1: BasicValueEnum<'ctx>,
value2: BasicValueEnum<'ctx>,