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++",
|
||||||
// "-lc++abi",
|
// "-lc++abi",
|
||||||
// "-lunwind", // TODO will eventually need this, see https://github.com/rtfeldman/roc/pull/554#discussion_r496370840
|
// "-lunwind", // TODO will eventually need this, see https://github.com/rtfeldman/roc/pull/554#discussion_r496370840
|
||||||
"-framework",
|
//"-framework",
|
||||||
"Security", // This "-framework Security" arg is needed for the `rand` crate in examples/cli
|
//"Security", // This "-framework Security" arg is needed for the `rand` crate in examples/cli
|
||||||
// Output
|
// Output
|
||||||
"-o",
|
"-o",
|
||||||
output_path.to_str().unwrap(), // app
|
output_path.to_str().unwrap(), // app
|
||||||
|
|
|
@ -665,26 +665,25 @@ pub fn listAppend(list: RocList, alignment: usize, element: Opaque, element_widt
|
||||||
return output;
|
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();
|
const size = list.len();
|
||||||
if (size <= count) {
|
const keep_count = size - drop_count;
|
||||||
|
if (size <= drop_count) {
|
||||||
return RocList.empty();
|
return RocList.empty();
|
||||||
}
|
}
|
||||||
if (list.bytes) |source_ptr| {
|
if (list.bytes) |source_ptr| {
|
||||||
var i: usize = 0;
|
const output = RocList.allocate(std.heap.c_allocator, alignment, keep_count, element_width);
|
||||||
|
|
||||||
const output = RocList.allocate(std.heap.c_allocator, alignment, size - count, element_width);
|
|
||||||
const target_ptr = output.bytes orelse unreachable;
|
const target_ptr = output.bytes orelse unreachable;
|
||||||
|
|
||||||
while (i < size - count) : (i += 1) {
|
@memcpy(target_ptr, source_ptr + drop_count * element_width, keep_count * element_width);
|
||||||
@memcpy(target_ptr + (i * element_width), source_ptr + ((i + count) * element_width), element_width);
|
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < drop_count) : (i += 1) {
|
||||||
|
const element = source_ptr + i * element_width;
|
||||||
|
dec(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (list.isUnique()) {
|
utils.decref(std.heap.c_allocator, alignment, list.bytes, size * element_width);
|
||||||
// std.heap.c_allocator.free(source_ptr);
|
|
||||||
// } else {
|
|
||||||
// utils.decref(std.heap.c_allocator, alignment, list.bytes, size * element_width);
|
|
||||||
// }
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3891,15 +3891,18 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
let original_wrapper = list.into_struct_value();
|
let original_wrapper = list.into_struct_value();
|
||||||
|
|
||||||
let count = load_symbol(scope, &args[1]);
|
let count = load_symbol(scope, &args[1]);
|
||||||
let inplace = get_inplace_from_layout(layout);
|
|
||||||
|
|
||||||
list_drop(
|
match list_layout {
|
||||||
env,
|
Layout::Builtin(Builtin::EmptyList) => empty_list(env),
|
||||||
inplace,
|
Layout::Builtin(Builtin::List(_, element_layout)) => list_drop(
|
||||||
original_wrapper,
|
env,
|
||||||
count.into_int_value(),
|
layout_ids,
|
||||||
list_layout,
|
original_wrapper,
|
||||||
)
|
count.into_int_value(),
|
||||||
|
element_layout,
|
||||||
|
),
|
||||||
|
_ => unreachable!("Invalid layout {:?} in List.drop", list_layout),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ListPrepend => {
|
ListPrepend => {
|
||||||
// List.prepend : List elem, elem -> List elem
|
// 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
|
/// List.drop : List elem, Nat -> List elem
|
||||||
pub fn list_drop<'a, 'ctx, 'env>(
|
pub fn list_drop<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
_inplace: InPlace,
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
original_wrapper: StructValue<'ctx>,
|
original_wrapper: StructValue<'ctx>,
|
||||||
count: IntValue<'ctx>,
|
count: IntValue<'ctx>,
|
||||||
list_layout: &Layout<'a>,
|
element_layout: &Layout<'a>,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
let (_, element_layout) = match *list_layout {
|
let dec_element_fn = build_dec_wrapper(env, layout_ids, &element_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),
|
|
||||||
};
|
|
||||||
call_bitcode_fn_returns_list(
|
call_bitcode_fn_returns_list(
|
||||||
env,
|
env,
|
||||||
&[
|
&[
|
||||||
|
@ -353,6 +338,7 @@ pub fn list_drop<'a, 'ctx, 'env>(
|
||||||
alignment_intvalue(env, &element_layout),
|
alignment_intvalue(env, &element_layout),
|
||||||
layout_width(env, &element_layout),
|
layout_width(env, &element_layout),
|
||||||
count.into(),
|
count.into(),
|
||||||
|
dec_element_fn.as_global_value().as_pointer_value().into(),
|
||||||
],
|
],
|
||||||
&bitcode::LIST_DROP,
|
&bitcode::LIST_DROP,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue