mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
Fix most of deref logic
Still doesn't handle empty lists properly.
This commit is contained in:
parent
f45d89270b
commit
85e5b0ff82
4 changed files with 28 additions and 40 deletions
|
@ -466,8 +466,8 @@ fn link_macos(
|
|||
"-lc++",
|
||||
// "-lc++abi",
|
||||
// "-lunwind", // TODO will eventually need this, see https://github.com/rtfeldman/roc/pull/554#discussion_r496370840
|
||||
"-framework",
|
||||
"Security", // This "-framework Security" arg is needed for the `rand` crate in examples/cli
|
||||
//"-framework",
|
||||
//"Security", // This "-framework Security" arg is needed for the `rand` crate in examples/cli
|
||||
// Output
|
||||
"-o",
|
||||
output_path.to_str().unwrap(), // app
|
||||
|
|
|
@ -665,26 +665,25 @@ pub fn listAppend(list: RocList, alignment: usize, element: Opaque, element_widt
|
|||
return output;
|
||||
}
|
||||
|
||||
pub fn listDrop(list: RocList, alignment: usize, element_width: usize, count: usize) callconv(.C) RocList {
|
||||
pub fn listDrop(list: RocList, alignment: usize, element_width: usize, drop_count: usize, dec: Dec) callconv(.C) RocList {
|
||||
const size = list.len();
|
||||
if (size <= count) {
|
||||
const keep_count = size - drop_count;
|
||||
if (size <= drop_count) {
|
||||
return RocList.empty();
|
||||
}
|
||||
if (list.bytes) |source_ptr| {
|
||||
var i: usize = 0;
|
||||
|
||||
const output = RocList.allocate(std.heap.c_allocator, alignment, size - count, element_width);
|
||||
const output = RocList.allocate(std.heap.c_allocator, alignment, keep_count, element_width);
|
||||
const target_ptr = output.bytes orelse unreachable;
|
||||
|
||||
while (i < size - count) : (i += 1) {
|
||||
@memcpy(target_ptr + (i * element_width), source_ptr + ((i + count) * element_width), element_width);
|
||||
@memcpy(target_ptr, source_ptr + drop_count * element_width, keep_count * element_width);
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < drop_count) : (i += 1) {
|
||||
const element = source_ptr + i * element_width;
|
||||
dec(element);
|
||||
}
|
||||
|
||||
// if (list.isUnique()) {
|
||||
// std.heap.c_allocator.free(source_ptr);
|
||||
// } else {
|
||||
// utils.decref(std.heap.c_allocator, alignment, list.bytes, size * element_width);
|
||||
// }
|
||||
utils.decref(std.heap.c_allocator, alignment, list.bytes, size * element_width);
|
||||
|
||||
return output;
|
||||
} else {
|
||||
|
|
|
@ -3891,15 +3891,18 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
let original_wrapper = list.into_struct_value();
|
||||
|
||||
let count = load_symbol(scope, &args[1]);
|
||||
let inplace = get_inplace_from_layout(layout);
|
||||
|
||||
list_drop(
|
||||
match list_layout {
|
||||
Layout::Builtin(Builtin::EmptyList) => empty_list(env),
|
||||
Layout::Builtin(Builtin::List(_, element_layout)) => list_drop(
|
||||
env,
|
||||
inplace,
|
||||
layout_ids,
|
||||
original_wrapper,
|
||||
count.into_int_value(),
|
||||
list_layout,
|
||||
)
|
||||
element_layout,
|
||||
),
|
||||
_ => unreachable!("Invalid layout {:?} in List.drop", list_layout),
|
||||
}
|
||||
}
|
||||
ListPrepend => {
|
||||
// List.prepend : List elem, elem -> List elem
|
||||
|
|
|
@ -325,27 +325,12 @@ pub fn list_append<'a, 'ctx, 'env>(
|
|||
/// List.drop : List elem, Nat -> List elem
|
||||
pub fn list_drop<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
_inplace: InPlace,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
original_wrapper: StructValue<'ctx>,
|
||||
count: IntValue<'ctx>,
|
||||
list_layout: &Layout<'a>,
|
||||
element_layout: &Layout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let (_, element_layout) = match *list_layout {
|
||||
Layout::Builtin(Builtin::EmptyList) => (
|
||||
InPlace::InPlace,
|
||||
// this pointer will never actually be dereferenced
|
||||
Layout::Builtin(Builtin::Int64),
|
||||
),
|
||||
Layout::Builtin(Builtin::List(memory_mode, elem_layout)) => (
|
||||
match memory_mode {
|
||||
MemoryMode::Unique => InPlace::InPlace,
|
||||
MemoryMode::Refcounted => InPlace::Clone,
|
||||
},
|
||||
*elem_layout,
|
||||
),
|
||||
|
||||
_ => unreachable!("Invalid layout {:?} in List.drop", list_layout),
|
||||
};
|
||||
let dec_element_fn = build_dec_wrapper(env, layout_ids, &element_layout);
|
||||
call_bitcode_fn_returns_list(
|
||||
env,
|
||||
&[
|
||||
|
@ -353,6 +338,7 @@ pub fn list_drop<'a, 'ctx, 'env>(
|
|||
alignment_intvalue(env, &element_layout),
|
||||
layout_width(env, &element_layout),
|
||||
count.into(),
|
||||
dec_element_fn.as_global_value().as_pointer_value().into(),
|
||||
],
|
||||
&bitcode::LIST_DROP,
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue