destruct record at high level

This commit is contained in:
satotake 2021-11-13 05:12:18 +00:00 committed by GitHub
parent 98d2c57edf
commit 2e073d57ea
5 changed files with 42 additions and 18 deletions

View file

@ -893,11 +893,10 @@ pub fn listSublist(
list: RocList, list: RocList,
alignment: u32, alignment: u32,
element_width: usize, element_width: usize,
rec: extern struct { len: usize, start: usize }, start: usize,
len: usize,
dec: Dec, dec: Dec,
) callconv(.C) RocList { ) callconv(.C) RocList {
const start = rec.start;
const len = rec.len;
if (list.bytes) |source_ptr| { if (list.bytes) |source_ptr| {
const size = list.len(); const size = list.len();
@ -922,9 +921,9 @@ pub fn listSublist(
utils.decref(list.bytes, size * element_width, alignment); utils.decref(list.bytes, size * element_width, alignment);
return output; return output;
} else { }
return RocList.empty();
} return RocList.empty();
} }
pub fn listTakeLast( pub fn listTakeLast(

View file

@ -2070,9 +2070,32 @@ fn list_sublist(symbol: Symbol, var_store: &mut VarStore) -> Def {
let sym_list = Symbol::ARG_1; let sym_list = Symbol::ARG_1;
let sym_rec = Symbol::ARG_2; let sym_rec = Symbol::ARG_2;
let start_var = var_store.fresh();
let len_var = var_store.fresh();
let get_start = Access {
record_var: rec_var,
ext_var: var_store.fresh(),
field_var: var_store.fresh(),
loc_expr: Box::new(no_region(Var(sym_rec))),
field: "start".into(),
};
let get_len = Access {
record_var: rec_var,
ext_var: var_store.fresh(),
field_var: var_store.fresh(),
loc_expr: Box::new(no_region(Var(sym_rec))),
field: "len".into(),
};
let body = RunLowLevel { let body = RunLowLevel {
op: LowLevel::ListSublist, op: LowLevel::ListSublist,
args: vec![(list_var, Var(sym_list)), (rec_var, Var(sym_rec))], args: vec![
(list_var, Var(sym_list)),
(start_var, get_start),
(len_var, get_len),
],
ret_var: list_var, ret_var: list_var,
}; };

View file

@ -5212,12 +5212,16 @@ fn run_low_level<'a, 'ctx, 'env>(
} }
ListSublist => { ListSublist => {
// List.sublist : List elem, { start : Nat, len : Nat } -> List elem // List.sublist : List elem, { start : Nat, len : Nat } -> List elem
debug_assert_eq!(args.len(), 2); //
// As a low-level, record is destructed
// List.sublist : List elem, start : Nat, len : Nat -> List elem
debug_assert_eq!(args.len(), 3);
let (list, list_layout) = load_symbol_and_layout(scope, &args[0]); let (list, list_layout) = load_symbol_and_layout(scope, &args[0]);
let original_wrapper = list.into_struct_value(); let original_wrapper = list.into_struct_value();
let rec = load_symbol(scope, &args[1]); let start = load_symbol(scope, &args[1]);
let len = load_symbol(scope, &args[2]);
match list_layout { match list_layout {
Layout::Builtin(Builtin::EmptyList) => empty_list(env), Layout::Builtin(Builtin::EmptyList) => empty_list(env),
@ -5225,7 +5229,8 @@ fn run_low_level<'a, 'ctx, 'env>(
env, env,
layout_ids, layout_ids,
original_wrapper, original_wrapper,
rec.into_struct_value(), start.into_int_value(),
len.into_int_value(),
element_layout, element_layout,
), ),
_ => unreachable!("Invalid layout {:?} in List.sublist", list_layout), _ => unreachable!("Invalid layout {:?} in List.sublist", list_layout),

View file

@ -343,7 +343,8 @@ pub fn list_sublist<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,
layout_ids: &mut LayoutIds<'a>, layout_ids: &mut LayoutIds<'a>,
original_wrapper: StructValue<'ctx>, original_wrapper: StructValue<'ctx>,
len_and_start: StructValue<'ctx>, start: IntValue<'ctx>,
len: IntValue<'ctx>,
element_layout: &Layout<'a>, element_layout: &Layout<'a>,
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
let dec_element_fn = build_dec_wrapper(env, layout_ids, element_layout); let dec_element_fn = build_dec_wrapper(env, layout_ids, element_layout);
@ -353,12 +354,8 @@ pub fn list_sublist<'a, 'ctx, 'env>(
pass_list_cc(env, original_wrapper.into()), pass_list_cc(env, original_wrapper.into()),
env.alignment_intvalue(element_layout), env.alignment_intvalue(element_layout),
layout_width(env, element_layout), layout_width(env, element_layout),
complex_bitcast( start.into(),
env.builder, len.into(),
len_and_start.into(),
env.str_list_c_abi().into(),
"to_i128",
),
dec_element_fn.as_global_value().as_pointer_value().into(), dec_element_fn.as_global_value().as_pointer_value().into(),
], ],
bitcode::LIST_SUBLIST, bitcode::LIST_SUBLIST,

View file

@ -968,7 +968,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
ListAppend => arena.alloc_slice_copy(&[owned, owned]), ListAppend => arena.alloc_slice_copy(&[owned, owned]),
ListTakeFirst => arena.alloc_slice_copy(&[owned, irrelevant]), ListTakeFirst => arena.alloc_slice_copy(&[owned, irrelevant]),
ListTakeLast => arena.alloc_slice_copy(&[owned, irrelevant]), ListTakeLast => arena.alloc_slice_copy(&[owned, irrelevant]),
ListSublist => arena.alloc_slice_copy(&[owned, irrelevant]), ListSublist => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),
ListDrop => arena.alloc_slice_copy(&[owned, irrelevant]), ListDrop => arena.alloc_slice_copy(&[owned, irrelevant]),
ListDropAt => arena.alloc_slice_copy(&[owned, irrelevant]), ListDropAt => arena.alloc_slice_copy(&[owned, irrelevant]),
ListSwap => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]), ListSwap => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),