mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
Add bounds checking to List.setInPlace
This commit is contained in:
parent
3e71b5a38d
commit
52bfe3ce9e
1 changed files with 24 additions and 14 deletions
|
@ -1105,7 +1105,7 @@ fn call_with_args<'a, 'ctx, 'env>(
|
||||||
let comparison = bounds_check_comparison(builder, elem_index, list_len);
|
let comparison = bounds_check_comparison(builder, elem_index, list_len);
|
||||||
|
|
||||||
// If the index is in bounds, clone and mutate in place.
|
// If the index is in bounds, clone and mutate in place.
|
||||||
let then_val: BasicValueEnum = {
|
let then_val = {
|
||||||
let (elem, elem_layout) = args[2];
|
let (elem, elem_layout) = args[2];
|
||||||
let (cloned_wrapper, array_data_ptr) = {
|
let (cloned_wrapper, array_data_ptr) = {
|
||||||
clone_list(
|
clone_list(
|
||||||
|
@ -1138,18 +1138,21 @@ fn call_with_args<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
debug_assert!(args.len() == 3);
|
debug_assert!(args.len() == 3);
|
||||||
|
|
||||||
let wrapper_struct = args[0].0.into_struct_value();
|
let original_wrapper = args[0].0.into_struct_value();
|
||||||
let elem_index = args[1].0.into_int_value();
|
let elem_index = args[1].0.into_int_value();
|
||||||
let (elem, _elem_layout) = args[2];
|
let (elem, _elem_layout) = args[2];
|
||||||
|
|
||||||
// Load the usize length
|
// Load the usize length
|
||||||
let _list_len = load_list_len(builder, wrapper_struct);
|
let list_len = load_list_len(builder, original_wrapper);
|
||||||
|
|
||||||
// TODO here, check to see if the requested index exceeds the length of the array.
|
// Bounds check: only proceed if index < length.
|
||||||
// If so, bail out and return the list unaltered.
|
// Otherwise, return the list unaltered.
|
||||||
|
let comparison = bounds_check_comparison(builder, elem_index, list_len);
|
||||||
|
|
||||||
|
// If the index is in bounds, clone and mutate in place.
|
||||||
|
let then_val = {
|
||||||
// Load the pointer to the elements
|
// Load the pointer to the elements
|
||||||
let array_data_ptr = load_list_ptr(builder, wrapper_struct);
|
let array_data_ptr = load_list_ptr(builder, original_wrapper);
|
||||||
|
|
||||||
// We already checked the bounds earlier.
|
// We already checked the bounds earlier.
|
||||||
let elem_ptr =
|
let elem_ptr =
|
||||||
|
@ -1159,7 +1162,14 @@ fn call_with_args<'a, 'ctx, 'env>(
|
||||||
builder.build_store(elem_ptr, elem);
|
builder.build_store(elem_ptr, elem);
|
||||||
|
|
||||||
// Return the wrapper unchanged, since pointer and length are unchanged
|
// Return the wrapper unchanged, since pointer and length are unchanged
|
||||||
BasicValueEnum::StructValue(wrapper_struct)
|
BasicValueEnum::StructValue(original_wrapper)
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the index was out of bounds, return the original list unaltered.
|
||||||
|
let else_val = BasicValueEnum::StructValue(original_wrapper);
|
||||||
|
let ret_type = original_wrapper.get_type();
|
||||||
|
|
||||||
|
build_basic_phi2(env, parent, comparison, then_val, else_val, ret_type.into())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let fn_val = env
|
let fn_val = env
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue