Merge remote-tracking branch 'origin/main' into str-unicode

This commit is contained in:
Richard Feldman 2024-01-21 12:29:34 -05:00
commit 2970fc4384
No known key found for this signature in database
GPG key ID: F1F21AA5B1D9E43B
78 changed files with 2747 additions and 2467 deletions

View file

@ -34,8 +34,8 @@ use crate::llvm::{
BuilderExt, FuncBorrowSpec, RocReturn,
},
build_list::{
list_append_unsafe, list_concat, list_drop_at, list_get_unsafe, list_len, list_map,
list_map2, list_map3, list_map4, list_prepend, list_release_excess_capacity,
layout_width, list_append_unsafe, list_concat, list_drop_at, list_get_unsafe, list_len,
list_map, list_map2, list_map3, list_map4, list_prepend, list_release_excess_capacity,
list_replace_unsafe, list_reserve, list_sort_with, list_sublist, list_swap,
list_symbol_to_c_abi, list_with_capacity, pass_update_mode,
},
@ -818,6 +818,31 @@ pub(crate) fn run_low_level<'a, 'ctx>(
bitcode::LIST_IS_UNIQUE,
)
}
ListClone => {
// List.clone : List a -> List a
arguments_with_layouts!((list, list_layout));
let element_layout = list_element_layout!(layout_interner, list_layout);
match update_mode {
UpdateMode::Immutable => {
//
call_list_bitcode_fn(
env,
&[list.into_struct_value()],
&[
env.alignment_intvalue(layout_interner, element_layout),
layout_width(env, layout_interner, element_layout),
],
BitcodeReturns::List,
bitcode::LIST_CLONE,
)
}
UpdateMode::InPlace => {
// we statically know the list is unique
list
}
}
}
NumToStr => {
// Num.toStr : Num a -> Str
arguments_with_layouts!((num, num_layout));

View file

@ -11,7 +11,7 @@ use roc_mono::layout::{InLayout, LayoutInterner, LayoutRepr, STLayoutInterner};
use crate::llvm::build::{load_roc_value, use_roc_value};
use super::{
build::{BuilderExt, Env},
build::{store_roc_value, BuilderExt, Env},
convert::basic_type_from_layout,
scope::Scope,
};
@ -50,19 +50,16 @@ impl<'ctx> RocStruct<'ctx> {
scope: &Scope<'a, 'ctx>,
sorted_fields: &[Symbol],
) -> Self {
let BuildStruct {
struct_type,
struct_val,
} = build_struct_helper(env, layout_interner, scope, sorted_fields);
let passed_by_ref = layout_repr.is_passed_by_reference(layout_interner);
if passed_by_ref {
let alloca = env.builder.new_build_alloca(struct_type, "struct_alloca");
env.builder.new_build_store(alloca, struct_val);
RocStruct::ByReference(alloca)
let struct_alloca =
build_struct_alloca_helper(env, layout_interner, scope, sorted_fields);
RocStruct::ByReference(struct_alloca)
} else {
RocStruct::ByValue(struct_val)
let struct_value =
build_struct_value_helper(env, layout_interner, scope, sorted_fields);
RocStruct::ByValue(struct_value)
}
}
@ -178,17 +175,12 @@ fn get_field_from_value<'ctx>(
.unwrap()
}
struct BuildStruct<'ctx> {
struct_type: StructType<'ctx>,
struct_val: StructValue<'ctx>,
}
fn build_struct_helper<'a, 'ctx>(
fn build_struct_value_helper<'a, 'ctx>(
env: &Env<'a, 'ctx, '_>,
layout_interner: &STLayoutInterner<'a>,
scope: &Scope<'a, 'ctx>,
sorted_fields: &[Symbol],
) -> BuildStruct<'ctx> {
) -> StructValue<'ctx> {
let ctx = env.context;
// Determine types
@ -227,12 +219,49 @@ fn build_struct_helper<'a, 'ctx>(
// Create the struct_type
let struct_type = ctx.struct_type(field_types.into_bump_slice(), false);
let struct_val = struct_from_fields(env, struct_type, field_vals.into_iter().enumerate());
struct_from_fields(env, struct_type, field_vals.into_iter().enumerate())
}
BuildStruct {
struct_type,
struct_val,
fn build_struct_alloca_helper<'a, 'ctx>(
env: &Env<'a, 'ctx, '_>,
layout_interner: &STLayoutInterner<'a>,
scope: &Scope<'a, 'ctx>,
sorted_fields: &[Symbol],
) -> PointerValue<'ctx> {
let ctx = env.context;
// Determine types
let num_fields = sorted_fields.len();
let mut field_types = AVec::with_capacity_in(num_fields, env.arena);
let mut field_expr_repr = AVec::with_capacity_in(num_fields, env.arena);
for symbol in sorted_fields.iter() {
// Zero-sized fields have no runtime representation.
// The layout of the struct expects them to be dropped!
let (field_expr, field_layout) = scope.load_symbol_and_layout(symbol);
if !layout_interner
.get_repr(field_layout)
.is_dropped_because_empty()
{
let field_repr = layout_interner.get_repr(field_layout);
let field_type = basic_type_from_layout(env, layout_interner, field_repr);
field_types.push(field_type);
field_expr_repr.push((field_expr, field_repr));
}
}
// Create the struct_type
let struct_type = ctx.struct_type(field_types.into_bump_slice(), false);
let alloca = env.builder.new_build_alloca(struct_type, "struct_alloca");
for (i, (field_expr, field_repr)) in field_expr_repr.into_iter().enumerate() {
let dst =
env.builder
.new_build_struct_gep(struct_type, alloca, i as u32, "struct_field_gep");
store_roc_value(env, layout_interner, field_repr, dst, field_expr);
}
alloca
}
pub fn struct_from_fields<'a, 'ctx, 'env, I>(