Merge remote-tracking branch 'origin/trunk' into can-builtins-simplify

This commit is contained in:
Folkert 2021-03-31 11:29:33 +02:00
commit 5d8d2bb030
46 changed files with 1914 additions and 522 deletions

View file

@ -713,56 +713,47 @@ pub fn list_len<'ctx>(
.into_int_value()
}
/// List.walk : List elem, (elem -> accum -> accum), accum -> accum
pub fn list_walk<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
layout_ids: &mut LayoutIds<'a>,
parent: FunctionValue<'ctx>,
list: BasicValueEnum<'ctx>,
element_layout: &Layout<'a>,
func: BasicValueEnum<'ctx>,
func_layout: &Layout<'a>,
default: BasicValueEnum<'ctx>,
default_layout: &Layout<'a>,
) -> BasicValueEnum<'ctx> {
list_walk_generic(
env,
layout_ids,
parent,
list,
element_layout,
func,
func_layout,
default,
default_layout,
&bitcode::LIST_WALK,
)
pub enum ListWalk {
Walk,
WalkBackwards,
WalkUntil,
WalkBackwardsUntil,
}
/// List.walkBackwards : List elem, (elem -> accum -> accum), accum -> accum
pub fn list_walk_backwards<'a, 'ctx, 'env>(
pub fn list_walk_help<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
layout_ids: &mut LayoutIds<'a>,
scope: &crate::llvm::build::Scope<'a, 'ctx>,
parent: FunctionValue<'ctx>,
list: BasicValueEnum<'ctx>,
element_layout: &Layout<'a>,
func: BasicValueEnum<'ctx>,
func_layout: &Layout<'a>,
default: BasicValueEnum<'ctx>,
default_layout: &Layout<'a>,
args: &[roc_module::symbol::Symbol],
variant: ListWalk,
) -> BasicValueEnum<'ctx> {
list_walk_generic(
env,
layout_ids,
parent,
list,
element_layout,
func,
func_layout,
default,
default_layout,
&bitcode::LIST_WALK_BACKWARDS,
)
use crate::llvm::build::load_symbol_and_layout;
debug_assert_eq!(args.len(), 3);
let (list, list_layout) = load_symbol_and_layout(scope, &args[0]);
let (func, func_layout) = load_symbol_and_layout(scope, &args[1]);
let (default, default_layout) = load_symbol_and_layout(scope, &args[2]);
match list_layout {
Layout::Builtin(Builtin::EmptyList) => default,
Layout::Builtin(Builtin::List(_, element_layout)) => list_walk_generic(
env,
layout_ids,
parent,
list,
element_layout,
func,
func_layout,
default,
default_layout,
variant,
),
_ => unreachable!("invalid list layout"),
}
}
fn list_walk_generic<'a, 'ctx, 'env>(
@ -775,10 +766,17 @@ fn list_walk_generic<'a, 'ctx, 'env>(
func_layout: &Layout<'a>,
default: BasicValueEnum<'ctx>,
default_layout: &Layout<'a>,
zig_function: &str,
variant: ListWalk,
) -> BasicValueEnum<'ctx> {
let builder = env.builder;
let zig_function = match variant {
ListWalk::Walk => bitcode::LIST_WALK,
ListWalk::WalkBackwards => bitcode::LIST_WALK_BACKWARDS,
ListWalk::WalkUntil => bitcode::LIST_WALK_UNTIL,
ListWalk::WalkBackwardsUntil => todo!(),
};
let u8_ptr = env.context.i8_type().ptr_type(AddressSpace::Generic);
let list_i128 = complex_bitcast(env.builder, list, env.context.i128_type().into(), "to_i128");
@ -811,21 +809,44 @@ fn list_walk_generic<'a, 'ctx, 'env>(
let result_ptr = env.builder.build_alloca(default.get_type(), "result");
call_void_bitcode_fn(
env,
&[
list_i128,
env.builder
.build_bitcast(transform_ptr, u8_ptr, "to_opaque"),
stepper_caller.into(),
env.builder.build_bitcast(default_ptr, u8_ptr, "to_u8_ptr"),
alignment_iv.into(),
element_width.into(),
default_width.into(),
env.builder.build_bitcast(result_ptr, u8_ptr, "to_opaque"),
],
zig_function,
);
match variant {
ListWalk::Walk | ListWalk::WalkBackwards => {
call_void_bitcode_fn(
env,
&[
list_i128,
env.builder
.build_bitcast(transform_ptr, u8_ptr, "to_opaque"),
stepper_caller.into(),
env.builder.build_bitcast(default_ptr, u8_ptr, "to_u8_ptr"),
alignment_iv.into(),
element_width.into(),
default_width.into(),
env.builder.build_bitcast(result_ptr, u8_ptr, "to_opaque"),
],
zig_function,
);
}
ListWalk::WalkUntil | ListWalk::WalkBackwardsUntil => {
let dec_element_fn = build_dec_wrapper(env, layout_ids, element_layout);
call_void_bitcode_fn(
env,
&[
list_i128,
env.builder
.build_bitcast(transform_ptr, u8_ptr, "to_opaque"),
stepper_caller.into(),
env.builder.build_bitcast(default_ptr, u8_ptr, "to_u8_ptr"),
alignment_iv.into(),
element_width.into(),
default_width.into(),
dec_element_fn.as_global_value().as_pointer_value().into(),
env.builder.build_bitcast(result_ptr, u8_ptr, "to_opaque"),
],
zig_function,
);
}
}
env.builder.build_load(result_ptr, "load_result")
}