mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
Merge remote-tracking branch 'origin/main' into glue-getters-rtfeldman
This commit is contained in:
commit
fdf1489df6
159 changed files with 4458 additions and 6232 deletions
|
@ -393,17 +393,36 @@ pub(crate) fn list_len<'ctx>(
|
|||
.into_int_value()
|
||||
}
|
||||
|
||||
/// List.capacity : List * -> Nat
|
||||
pub(crate) fn list_capacity<'ctx>(
|
||||
pub(crate) fn list_capacity_or_ref_ptr<'ctx>(
|
||||
builder: &Builder<'ctx>,
|
||||
wrapper_struct: StructValue<'ctx>,
|
||||
) -> IntValue<'ctx> {
|
||||
builder
|
||||
.build_extract_value(wrapper_struct, Builtin::WRAPPER_CAPACITY, "list_capacity")
|
||||
.build_extract_value(
|
||||
wrapper_struct,
|
||||
Builtin::WRAPPER_CAPACITY,
|
||||
"list_capacity_or_ref_ptr",
|
||||
)
|
||||
.unwrap()
|
||||
.into_int_value()
|
||||
}
|
||||
|
||||
// Gets a pointer to just after the refcount for a list or seamless slice.
|
||||
// The value is just after the refcount so that normal lists and seamless slices can share code paths easily.
|
||||
pub(crate) fn list_refcount_ptr<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
wrapper_struct: StructValue<'ctx>,
|
||||
) -> PointerValue<'ctx> {
|
||||
call_list_bitcode_fn(
|
||||
env,
|
||||
&[wrapper_struct],
|
||||
&[],
|
||||
BitcodeReturns::Basic,
|
||||
bitcode::LIST_REFCOUNT_PTR,
|
||||
)
|
||||
.into_pointer_value()
|
||||
}
|
||||
|
||||
pub(crate) fn destructure<'ctx>(
|
||||
builder: &Builder<'ctx>,
|
||||
wrapper_struct: StructValue<'ctx>,
|
||||
|
@ -801,11 +820,7 @@ pub(crate) fn decref<'a, 'ctx, 'env>(
|
|||
wrapper_struct: StructValue<'ctx>,
|
||||
alignment: u32,
|
||||
) {
|
||||
let (_, pointer) = load_list(
|
||||
env.builder,
|
||||
wrapper_struct,
|
||||
env.context.i8_type().ptr_type(AddressSpace::default()),
|
||||
);
|
||||
let refcount_ptr = list_refcount_ptr(env, wrapper_struct);
|
||||
|
||||
crate::llvm::refcounting::decref_pointer_check_null(env, pointer, alignment);
|
||||
crate::llvm::refcounting::decref_pointer_check_null(env, refcount_ptr, alignment);
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ use crate::llvm::{
|
|||
load_roc_value, roc_function_call, BuilderExt, RocReturn,
|
||||
},
|
||||
build_list::{
|
||||
list_append_unsafe, list_capacity, list_concat, list_drop_at, list_get_unsafe, list_len,
|
||||
list_map, list_map2, list_map3, list_map4, list_prepend, list_replace_unsafe, list_reserve,
|
||||
list_append_unsafe, list_concat, list_drop_at, list_get_unsafe, list_len, list_map,
|
||||
list_map2, list_map3, list_map4, list_prepend, list_replace_unsafe, list_reserve,
|
||||
list_sort_with, list_sublist, list_swap, list_symbol_to_c_abi, list_with_capacity,
|
||||
pass_update_mode,
|
||||
},
|
||||
|
@ -632,10 +632,16 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
|
|||
list_len(env.builder, list.into_struct_value()).into()
|
||||
}
|
||||
ListGetCapacity => {
|
||||
// List.capacity : List * -> Nat
|
||||
// List.capacity: List a -> Nat
|
||||
arguments!(list);
|
||||
|
||||
list_capacity(env.builder, list.into_struct_value()).into()
|
||||
call_list_bitcode_fn(
|
||||
env,
|
||||
&[list.into_struct_value()],
|
||||
&[],
|
||||
BitcodeReturns::Basic,
|
||||
bitcode::LIST_CAPACITY,
|
||||
)
|
||||
}
|
||||
ListWithCapacity => {
|
||||
// List.withCapacity : Nat -> List a
|
||||
|
@ -848,9 +854,24 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
NumAbs | NumNeg | NumRound | NumSqrtUnchecked | NumLogUnchecked | NumSin | NumCos
|
||||
| NumCeiling | NumFloor | NumToFrac | NumIsFinite | NumAtan | NumAcos | NumAsin
|
||||
| NumToIntChecked => {
|
||||
NumAbs
|
||||
| NumNeg
|
||||
| NumRound
|
||||
| NumSqrtUnchecked
|
||||
| NumLogUnchecked
|
||||
| NumSin
|
||||
| NumCos
|
||||
| NumCeiling
|
||||
| NumFloor
|
||||
| NumToFrac
|
||||
| NumIsFinite
|
||||
| NumAtan
|
||||
| NumAcos
|
||||
| NumAsin
|
||||
| NumToIntChecked
|
||||
| NumCountLeadingZeroBits
|
||||
| NumCountTrailingZeroBits
|
||||
| NumCountOneBits => {
|
||||
arguments_with_layouts!((arg, arg_layout));
|
||||
|
||||
match layout_interner.get(arg_layout) {
|
||||
|
@ -914,6 +935,28 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
|
|||
bitcode::NUM_BYTES_TO_U32,
|
||||
)
|
||||
}
|
||||
NumBytesToU64 => {
|
||||
arguments!(list, position);
|
||||
|
||||
call_list_bitcode_fn(
|
||||
env,
|
||||
&[list.into_struct_value()],
|
||||
&[position],
|
||||
BitcodeReturns::Basic,
|
||||
bitcode::NUM_BYTES_TO_U64,
|
||||
)
|
||||
}
|
||||
NumBytesToU128 => {
|
||||
arguments!(list, position);
|
||||
|
||||
call_list_bitcode_fn(
|
||||
env,
|
||||
&[list.into_struct_value()],
|
||||
&[position],
|
||||
BitcodeReturns::Basic,
|
||||
bitcode::NUM_BYTES_TO_U128,
|
||||
)
|
||||
}
|
||||
NumCompare => {
|
||||
arguments_with_layouts!((lhs_arg, lhs_layout), (rhs_arg, rhs_layout));
|
||||
|
||||
|
@ -2045,6 +2088,19 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
|||
complex_bitcast_check_size(env, result, return_type.into(), "cast_bitpacked")
|
||||
}
|
||||
}
|
||||
NumCountLeadingZeroBits => call_bitcode_fn(
|
||||
env,
|
||||
&[arg.into()],
|
||||
&bitcode::NUM_COUNT_LEADING_ZERO_BITS[arg_width],
|
||||
),
|
||||
NumCountTrailingZeroBits => call_bitcode_fn(
|
||||
env,
|
||||
&[arg.into()],
|
||||
&bitcode::NUM_COUNT_TRAILING_ZERO_BITS[arg_width],
|
||||
),
|
||||
NumCountOneBits => {
|
||||
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_COUNT_ONE_BITS[arg_width])
|
||||
}
|
||||
_ => {
|
||||
unreachable!("Unrecognized int unary operation: {:?}", op);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@ use crate::llvm::build::{
|
|||
add_func, cast_basic_basic, get_tag_id, tag_pointer_clear_tag_id, use_roc_value, Env,
|
||||
FAST_CALL_CONV,
|
||||
};
|
||||
use crate::llvm::build_list::{incrementing_elem_loop, list_capacity, load_list};
|
||||
use crate::llvm::build_list::{
|
||||
incrementing_elem_loop, list_capacity_or_ref_ptr, list_refcount_ptr, load_list,
|
||||
};
|
||||
use crate::llvm::convert::{basic_type_from_layout, zig_str_type, RocUnion};
|
||||
use bumpalo::collections::Vec;
|
||||
use inkwell::basic_block::BasicBlock;
|
||||
|
@ -691,22 +693,23 @@ fn modify_refcount_list_help<'a, 'ctx, 'env>(
|
|||
let parent = fn_val;
|
||||
let original_wrapper = arg_val.into_struct_value();
|
||||
|
||||
let len = list_capacity(builder, original_wrapper);
|
||||
// We use the raw capacity to ensure we always decrement the refcount of seamless slices.
|
||||
let capacity = list_capacity_or_ref_ptr(builder, original_wrapper);
|
||||
|
||||
let is_non_empty = builder.build_int_compare(
|
||||
IntPredicate::UGT,
|
||||
len,
|
||||
capacity,
|
||||
env.ptr_int().const_zero(),
|
||||
"len > 0",
|
||||
"cap > 0",
|
||||
);
|
||||
|
||||
// build blocks
|
||||
let modification_block = ctx.append_basic_block(parent, "modification_block");
|
||||
let modification_list_block = ctx.append_basic_block(parent, "modification_list_block");
|
||||
let cont_block = ctx.append_basic_block(parent, "modify_rc_list_cont");
|
||||
|
||||
builder.build_conditional_branch(is_non_empty, modification_block, cont_block);
|
||||
builder.build_conditional_branch(is_non_empty, modification_list_block, cont_block);
|
||||
|
||||
builder.position_at_end(modification_block);
|
||||
builder.position_at_end(modification_list_block);
|
||||
|
||||
if layout_interner.contains_refcounted(element_layout) {
|
||||
let ptr_type = basic_type_from_layout(env, layout_interner, element_layout)
|
||||
|
@ -737,7 +740,8 @@ fn modify_refcount_list_help<'a, 'ctx, 'env>(
|
|||
);
|
||||
}
|
||||
|
||||
let refcount_ptr = PointerToRefcount::from_list_wrapper(env, original_wrapper);
|
||||
let refcount_ptr =
|
||||
PointerToRefcount::from_ptr_to_data(env, list_refcount_ptr(env, original_wrapper));
|
||||
let call_mode = mode_to_call_mode(fn_val, mode);
|
||||
refcount_ptr.modify(call_mode, layout, env, layout_interner);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue