mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
all tests passing
This commit is contained in:
parent
bd0f02c542
commit
180575852a
4 changed files with 65 additions and 14 deletions
|
@ -2372,6 +2372,25 @@ fn list_literal<'a, 'ctx, 'env>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn load_roc_value<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout: Layout<'a>,
|
||||
source: PointerValue<'ctx>,
|
||||
name: &str,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
if layout.is_passed_by_reference() {
|
||||
let alloca = env
|
||||
.builder
|
||||
.build_alloca(basic_type_from_layout(env, &layout), name);
|
||||
|
||||
store_roc_value(env, layout, alloca, source.into());
|
||||
|
||||
alloca.into()
|
||||
} else {
|
||||
env.builder.build_load(source, name)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn store_roc_value_opaque<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout: Layout<'a>,
|
||||
|
@ -3318,7 +3337,7 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx, 'env>(
|
|||
.unwrap()
|
||||
.into_pointer_value();
|
||||
|
||||
builder.build_store(output_arg, call_result);
|
||||
store_roc_value(env, return_layout, output_arg, call_result);
|
||||
builder.build_return(None);
|
||||
|
||||
c_function
|
||||
|
@ -4218,8 +4237,10 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
|||
|
||||
// NOTE this may be incorrect in the long run
|
||||
// here we load any argument that is a pointer
|
||||
for param in evaluator_arguments.iter_mut() {
|
||||
if param.is_pointer_value() {
|
||||
let closure_layout = lambda_set.runtime_representation();
|
||||
let layouts_it = arguments.iter().chain(std::iter::once(&closure_layout));
|
||||
for (param, layout) in evaluator_arguments.iter_mut().zip(layouts_it) {
|
||||
if param.is_pointer_value() && !layout.is_passed_by_reference() {
|
||||
*param = builder.build_load(param.into_pointer_value(), "load_param");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -780,7 +780,15 @@ fn hash_list<'a, 'ctx, 'env>(
|
|||
env.builder.build_store(result, answer);
|
||||
};
|
||||
|
||||
incrementing_elem_loop(env, parent, ptr, length, "current_index", loop_fn);
|
||||
incrementing_elem_loop(
|
||||
env,
|
||||
parent,
|
||||
*element_layout,
|
||||
ptr,
|
||||
length,
|
||||
"current_index",
|
||||
loop_fn,
|
||||
);
|
||||
|
||||
env.builder.build_unconditional_branch(done_block);
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ use morphic_lib::UpdateMode;
|
|||
use roc_builtins::bitcode;
|
||||
use roc_mono::layout::{Builtin, Layout, LayoutIds};
|
||||
|
||||
use super::build::load_roc_value;
|
||||
|
||||
pub fn pass_update_mode<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
update_mode: UpdateMode,
|
||||
|
@ -216,10 +218,15 @@ pub fn list_get_unsafe<'a, 'ctx, 'env>(
|
|||
|
||||
// Assume the bounds have already been checked earlier
|
||||
// (e.g. by List.get or List.first, which wrap List.#getUnsafe)
|
||||
let elem_ptr =
|
||||
unsafe { builder.build_in_bounds_gep(array_data_ptr, &[elem_index], "elem") };
|
||||
let elem_ptr = unsafe {
|
||||
builder.build_in_bounds_gep(array_data_ptr, &[elem_index], "list_get_element")
|
||||
};
|
||||
|
||||
let result = builder.build_load(elem_ptr, "List.get");
|
||||
let result = if elem_layout.is_passed_by_reference() {
|
||||
elem_ptr.into()
|
||||
} else {
|
||||
builder.build_load(elem_ptr, "list_get_load_element")
|
||||
};
|
||||
|
||||
increment_refcount_layout(env, parent, layout_ids, 1, result, elem_layout);
|
||||
|
||||
|
@ -975,6 +982,7 @@ where
|
|||
pub fn incrementing_elem_loop<'a, 'ctx, 'env, LoopFn>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
parent: FunctionValue<'ctx>,
|
||||
element_layout: Layout<'a>,
|
||||
ptr: PointerValue<'ctx>,
|
||||
len: IntValue<'ctx>,
|
||||
index_name: &str,
|
||||
|
@ -987,9 +995,14 @@ where
|
|||
|
||||
incrementing_index_loop(env, parent, len, index_name, |index| {
|
||||
// The pointer to the element in the list
|
||||
let elem_ptr = unsafe { builder.build_in_bounds_gep(ptr, &[index], "load_index") };
|
||||
let element_ptr = unsafe { builder.build_in_bounds_gep(ptr, &[index], "load_index") };
|
||||
|
||||
let elem = builder.build_load(elem_ptr, "get_elem");
|
||||
let elem = load_roc_value(
|
||||
env,
|
||||
element_layout,
|
||||
element_ptr,
|
||||
"incrementing_element_loop_load",
|
||||
);
|
||||
|
||||
loop_fn(index, elem);
|
||||
})
|
||||
|
|
|
@ -765,7 +765,15 @@ fn modify_refcount_list_help<'a, 'ctx, 'env>(
|
|||
);
|
||||
};
|
||||
|
||||
incrementing_elem_loop(env, parent, ptr, len, "modify_rc_index", loop_fn);
|
||||
incrementing_elem_loop(
|
||||
env,
|
||||
parent,
|
||||
*element_layout,
|
||||
ptr,
|
||||
len,
|
||||
"modify_rc_index",
|
||||
loop_fn,
|
||||
);
|
||||
}
|
||||
|
||||
let refcount_ptr = PointerToRefcount::from_list_wrapper(env, original_wrapper);
|
||||
|
@ -1616,7 +1624,6 @@ fn modify_refcount_union<'a, 'ctx, 'env>(
|
|||
None => {
|
||||
let basic_type = basic_type_from_layout_1(env, &layout);
|
||||
let function_value = build_header(env, basic_type, mode, &fn_name);
|
||||
dbg!(function_value);
|
||||
|
||||
modify_refcount_union_help(
|
||||
env,
|
||||
|
@ -1668,8 +1675,6 @@ fn modify_refcount_union_help<'a, 'ctx, 'env>(
|
|||
|
||||
let before_block = env.builder.get_insert_block().expect("to be in a function");
|
||||
|
||||
dbg!(fn_val, arg_ptr);
|
||||
|
||||
// read the tag_id
|
||||
let tag_id_ptr = env
|
||||
.builder
|
||||
|
@ -1729,7 +1734,11 @@ fn modify_refcount_union_help<'a, 'ctx, 'env>(
|
|||
.build_struct_gep(cast_tag_data_pointer, i as u32, "modify_tag_field")
|
||||
.unwrap();
|
||||
|
||||
let field_value = env.builder.build_load(field_ptr, "field_value");
|
||||
let field_value = if field_layout.is_passed_by_reference() {
|
||||
field_ptr.into()
|
||||
} else {
|
||||
env.builder.build_load(field_ptr, "field_value")
|
||||
};
|
||||
|
||||
modify_refcount_layout_help(
|
||||
env,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue