Update List.sublist to no longer use Nat

This commit is contained in:
Richard Feldman 2024-01-22 23:12:18 -05:00
parent 2cf7b5b5ca
commit a71188dc30
No known key found for this signature in database
GPG key ID: F1F21AA5B1D9E43B
4 changed files with 29 additions and 12 deletions

View file

@ -615,12 +615,12 @@ pub fn listSublist(
list: RocList,
alignment: u32,
element_width: usize,
start: usize,
len: usize,
start_u64: u64,
len_u64: u64,
dec: Dec,
) callconv(.C) RocList {
const size = list.len();
if (len == 0 or start >= size) {
if (size == 0 or start_u64 >= @as(u64, @intCast(size))) {
// Decrement the reference counts of all elements.
if (list.bytes) |source_ptr| {
var i: usize = 0;
@ -639,9 +639,26 @@ pub fn listSublist(
}
if (list.bytes) |source_ptr| {
const keep_len = @min(len, size - start);
// This cast is lossless because we would have early-returned already
// if `start_u64` were greater than `size`, and `size` fits in usize.
const start = @as(usize, @intCast(start_u64));
const drop_start_len = start;
const drop_end_len = size - (start + keep_len);
// (size - start) can't overflow because we would have early-returned already
// if `start` were greater than `size`.
const size_minus_start = size - start;
// This outer cast to usize is lossless. size, start, and size_minus_start all fit in usize,
// and @min guarantees that if `len_u64` gets returned, it's because it was smaller
// than something that fit in usize.
const keep_len = @as(usize, @intCast(@min(len_u64, @as(u64, @intCast(size_minus_start)))));
// This can't overflow because if len > size_minus_start,
// then keep_len == size_minus_start and this will be 0.
// Alternatively, if len <= size_minus_start, then keep_len will
// be equal to len, meaning keep_len <= size_minus_start too,
// which in turn means this won't overflow.
const drop_end_len = size_minus_start - keep_len;
// Decrement the reference counts of elements before `start`.
var i: usize = 0;

View file

@ -1867,8 +1867,8 @@ trait Backend<'a> {
// list: RocList,
// alignment: u32,
// element_width: usize,
// start: usize,
// len: usize,
// start: u64,
// len: u64,
// dec: Dec,
let list = args[0];
@ -1894,8 +1894,8 @@ trait Backend<'a> {
arg_layouts[0],
Layout::U32,
layout_usize,
arg_layouts[1],
arg_layouts[2],
Layout::U64,
Layout::U64,
layout_usize,
];

View file

@ -274,7 +274,7 @@ pub(crate) fn list_swap<'a, 'ctx>(
)
}
/// List.sublist : List elem, { start : Nat, len : Nat } -> List elem
/// List.sublist : List elem, { start : U64, len : U64 } -> List elem
pub(crate) fn list_sublist<'a, 'ctx>(
env: &Env<'a, 'ctx, '_>,
layout_interner: &STLayoutInterner<'a>,

View file

@ -676,8 +676,8 @@ impl<'a> LowLevelCall<'a> {
// list: RocList, i32
// alignment: u32, i32
// element_width: usize, i32
// start: usize, i32
// len: usize, i32
// start: u64, i64
// len: u64, i64
// dec: Dec, i32
backend.storage.load_symbols_for_call(