mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
fix the issues
This commit is contained in:
parent
3e5d2351a5
commit
fd9b826398
6 changed files with 100 additions and 80 deletions
|
@ -1,6 +1,6 @@
|
||||||
/// Helpers for interacting with the zig that generates bitcode
|
/// Helpers for interacting with the zig that generates bitcode
|
||||||
use crate::debug_info_init;
|
use crate::debug_info_init;
|
||||||
use crate::llvm::build::{struct_from_fields, Env, C_CALL_CONV, FAST_CALL_CONV};
|
use crate::llvm::build::{struct_from_fields, Env, C_CALL_CONV, FAST_CALL_CONV, TAG_DATA_INDEX};
|
||||||
use crate::llvm::convert::basic_type_from_layout;
|
use crate::llvm::convert::basic_type_from_layout;
|
||||||
use crate::llvm::refcounting::{
|
use crate::llvm::refcounting::{
|
||||||
decrement_refcount_layout, increment_n_refcount_layout, increment_refcount_layout,
|
decrement_refcount_layout, increment_n_refcount_layout, increment_refcount_layout,
|
||||||
|
@ -155,7 +155,23 @@ fn build_has_tag_id_help<'a, 'ctx, 'env>(
|
||||||
"compare",
|
"compare",
|
||||||
);
|
);
|
||||||
|
|
||||||
let field_vals = [(0, answer.into()), (1, *tag_value_ptr)];
|
let tag_data_ptr = {
|
||||||
|
let data_index = env
|
||||||
|
.context
|
||||||
|
.i64_type()
|
||||||
|
.const_int(TAG_DATA_INDEX as u64, false);
|
||||||
|
|
||||||
|
let ptr = unsafe {
|
||||||
|
env.builder.build_gep(
|
||||||
|
tag_value_ptr.into_pointer_value(),
|
||||||
|
&[data_index],
|
||||||
|
"get_data_ptr",
|
||||||
|
)
|
||||||
|
};
|
||||||
|
env.builder.build_bitcast(ptr, i8_ptr_type, "to_opaque")
|
||||||
|
};
|
||||||
|
|
||||||
|
let field_vals = [(0, answer.into()), (1, tag_data_ptr)];
|
||||||
|
|
||||||
let output = struct_from_fields(env, output_type, field_vals.iter().copied());
|
let output = struct_from_fields(env, output_type, field_vals.iter().copied());
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@ use crate::llvm::build_str::{
|
||||||
};
|
};
|
||||||
use crate::llvm::compare::{generic_eq, generic_neq};
|
use crate::llvm::compare::{generic_eq, generic_neq};
|
||||||
use crate::llvm::convert::{
|
use crate::llvm::convert::{
|
||||||
basic_type_from_builtin, basic_type_from_layout, basic_type_from_layout_old, block_of_memory,
|
basic_type_from_builtin, basic_type_from_layout, block_of_memory, block_of_memory_slices,
|
||||||
block_of_memory_slices, ptr_int,
|
ptr_int,
|
||||||
};
|
};
|
||||||
use crate::llvm::refcounting::{
|
use crate::llvm::refcounting::{
|
||||||
decrement_refcount_layout, increment_refcount_layout, PointerToRefcount,
|
decrement_refcount_layout, increment_refcount_layout, PointerToRefcount,
|
||||||
|
@ -946,7 +946,6 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
Struct(sorted_fields) => {
|
Struct(sorted_fields) => {
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
let builder = env.builder;
|
|
||||||
|
|
||||||
// Determine types
|
// Determine types
|
||||||
let num_fields = sorted_fields.len();
|
let num_fields = sorted_fields.len();
|
||||||
|
@ -1068,8 +1067,6 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
tag_id,
|
tag_id,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let tag_layout = Layout::Union(UnionLayout::NonRecursive(fields));
|
|
||||||
|
|
||||||
debug_assert!(*union_size > 1);
|
debug_assert!(*union_size > 1);
|
||||||
|
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
|
@ -1113,7 +1110,22 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the struct_type
|
// Create the struct_type
|
||||||
let data_ptr = reserve_with_refcount(env, &tag_layout);
|
let basic_type = block_of_memory_slices(env.context, fields, env.ptr_bytes);
|
||||||
|
|
||||||
|
let stack_size = fields
|
||||||
|
.iter()
|
||||||
|
.map(|tag| tag.iter().map(|l| l.stack_size(env.ptr_bytes)).sum())
|
||||||
|
.max()
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
let alignment_bytes = fields
|
||||||
|
.iter()
|
||||||
|
.map(|tag| tag.iter().map(|l| l.alignment_bytes(env.ptr_bytes)))
|
||||||
|
.flatten()
|
||||||
|
.max()
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
let data_ptr = reserve_with_refcount_help(env, basic_type, stack_size, alignment_bytes);
|
||||||
let struct_type = ctx.struct_type(field_types.into_bump_slice(), false);
|
let struct_type = ctx.struct_type(field_types.into_bump_slice(), false);
|
||||||
let struct_ptr = env
|
let struct_ptr = env
|
||||||
.builder
|
.builder
|
||||||
|
@ -1147,9 +1159,6 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
debug_assert_eq!(*tag_id, 0);
|
debug_assert_eq!(*tag_id, 0);
|
||||||
debug_assert_eq!(arguments.len(), fields.len());
|
debug_assert_eq!(arguments.len(), fields.len());
|
||||||
|
|
||||||
let struct_layout =
|
|
||||||
Layout::Union(UnionLayout::NonRecursive(env.arena.alloc([*fields])));
|
|
||||||
|
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
|
|
||||||
|
@ -1188,7 +1197,14 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the struct_type
|
// Create the struct_type
|
||||||
let data_ptr = reserve_with_refcount(env, &struct_layout);
|
let basic_type = block_of_memory_slices(env.context, &[*fields], env.ptr_bytes);
|
||||||
|
|
||||||
|
// layout we abuse to get the right stack size and alignment
|
||||||
|
let false_layout = Layout::Struct(fields);
|
||||||
|
let stack_size = false_layout.stack_size(env.ptr_bytes);
|
||||||
|
let alignment_bytes = false_layout.alignment_bytes(env.ptr_bytes);
|
||||||
|
let data_ptr = reserve_with_refcount_help(env, basic_type, stack_size, alignment_bytes);
|
||||||
|
|
||||||
let struct_type = ctx.struct_type(field_types.into_bump_slice(), false);
|
let struct_type = ctx.struct_type(field_types.into_bump_slice(), false);
|
||||||
let struct_ptr = env
|
let struct_ptr = env
|
||||||
.builder
|
.builder
|
||||||
|
@ -1222,8 +1238,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
tag_id,
|
tag_id,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let tag_layout = Layout::Union(UnionLayout::NonRecursive(fields));
|
let tag_struct_type = block_of_memory_slices(env.context, fields, env.ptr_bytes);
|
||||||
let tag_struct_type = basic_type_from_layout(env, &tag_layout);
|
|
||||||
if *tag_id == *nullable_id as u8 {
|
if *tag_id == *nullable_id as u8 {
|
||||||
let output_type = tag_struct_type.ptr_type(AddressSpace::Generic);
|
let output_type = tag_struct_type.ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
|
@ -1280,7 +1295,22 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the struct_type
|
// Create the struct_type
|
||||||
let data_ptr = reserve_with_refcount(env, &tag_layout);
|
let basic_type = block_of_memory_slices(env.context, fields, env.ptr_bytes);
|
||||||
|
|
||||||
|
let stack_size = fields
|
||||||
|
.iter()
|
||||||
|
.map(|tag| tag.iter().map(|l| l.stack_size(env.ptr_bytes)).sum())
|
||||||
|
.max()
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
let alignment_bytes = fields
|
||||||
|
.iter()
|
||||||
|
.map(|tag| tag.iter().map(|l| l.alignment_bytes(env.ptr_bytes)))
|
||||||
|
.flatten()
|
||||||
|
.max()
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
let data_ptr = reserve_with_refcount_help(env, basic_type, stack_size, alignment_bytes);
|
||||||
let struct_type = ctx.struct_type(field_types.into_bump_slice(), false);
|
let struct_type = ctx.struct_type(field_types.into_bump_slice(), false);
|
||||||
let struct_ptr = env
|
let struct_ptr = env
|
||||||
.builder
|
.builder
|
||||||
|
@ -1379,10 +1409,11 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the struct_type
|
// Create the struct_type
|
||||||
let data_ptr = reserve_with_refcount(
|
let basic_type = block_of_memory_slices(env.context, &[other_fields], env.ptr_bytes);
|
||||||
env,
|
let false_layout = Layout::Struct(other_fields);
|
||||||
&Layout::Union(UnionLayout::NonRecursive(&[other_fields])),
|
let stack_size = false_layout.stack_size(env.ptr_bytes);
|
||||||
);
|
let alignment_bytes = false_layout.alignment_bytes(env.ptr_bytes);
|
||||||
|
let data_ptr = reserve_with_refcount_help(env, basic_type, stack_size, alignment_bytes);
|
||||||
|
|
||||||
let struct_type = ctx.struct_type(field_types.into_bump_slice(), false);
|
let struct_type = ctx.struct_type(field_types.into_bump_slice(), false);
|
||||||
let struct_ptr = env
|
let struct_ptr = env
|
||||||
|
@ -1714,17 +1745,30 @@ fn lookup_at_index_ptr<'a, 'ctx, 'env>(
|
||||||
pub fn reserve_with_refcount<'a, 'ctx, 'env>(
|
pub fn reserve_with_refcount<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
layout: &Layout<'a>,
|
layout: &Layout<'a>,
|
||||||
|
) -> PointerValue<'ctx> {
|
||||||
|
let stack_size = layout.stack_size(env.ptr_bytes);
|
||||||
|
let alignment_bytes = layout.alignment_bytes(env.ptr_bytes);
|
||||||
|
|
||||||
|
let basic_type = basic_type_from_layout(env, layout);
|
||||||
|
|
||||||
|
reserve_with_refcount_help(env, basic_type, stack_size, alignment_bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_with_refcount_help<'a, 'ctx, 'env>(
|
||||||
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
basic_type: impl BasicType<'ctx>,
|
||||||
|
stack_size: u32,
|
||||||
|
alignment_bytes: u32,
|
||||||
) -> PointerValue<'ctx> {
|
) -> PointerValue<'ctx> {
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
|
|
||||||
let len_type = env.ptr_int();
|
let len_type = env.ptr_int();
|
||||||
|
|
||||||
let value_bytes = layout.stack_size(env.ptr_bytes);
|
let value_bytes_intvalue = len_type.const_int(stack_size as u64, false);
|
||||||
let value_bytes_intvalue = len_type.const_int(value_bytes as u64, false);
|
|
||||||
|
|
||||||
let rc1 = crate::llvm::refcounting::refcount_1(ctx, env.ptr_bytes);
|
let rc1 = crate::llvm::refcounting::refcount_1(ctx, env.ptr_bytes);
|
||||||
|
|
||||||
allocate_with_refcount_help(env, layout, value_bytes_intvalue, rc1)
|
allocate_with_refcount_help(env, basic_type, alignment_bytes, value_bytes_intvalue, rc1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn allocate_with_refcount<'a, 'ctx, 'env>(
|
pub fn allocate_with_refcount<'a, 'ctx, 'env>(
|
||||||
|
@ -1742,17 +1786,17 @@ pub fn allocate_with_refcount<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
pub fn allocate_with_refcount_help<'a, 'ctx, 'env>(
|
pub fn allocate_with_refcount_help<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
layout: &Layout<'a>,
|
value_type: impl BasicType<'ctx>,
|
||||||
|
alignment_bytes: u32,
|
||||||
number_of_data_bytes: IntValue<'ctx>,
|
number_of_data_bytes: IntValue<'ctx>,
|
||||||
initial_refcount: IntValue<'ctx>,
|
initial_refcount: IntValue<'ctx>,
|
||||||
) -> PointerValue<'ctx> {
|
) -> PointerValue<'ctx> {
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
|
|
||||||
let value_type = basic_type_from_layout_old(env, layout);
|
|
||||||
let len_type = env.ptr_int();
|
let len_type = env.ptr_int();
|
||||||
|
|
||||||
let extra_bytes = layout.alignment_bytes(env.ptr_bytes).max(env.ptr_bytes);
|
let extra_bytes = alignment_bytes.max(env.ptr_bytes);
|
||||||
|
|
||||||
let ptr = {
|
let ptr = {
|
||||||
// number of bytes we will allocated
|
// number of bytes we will allocated
|
||||||
|
@ -1762,7 +1806,7 @@ pub fn allocate_with_refcount_help<'a, 'ctx, 'env>(
|
||||||
"add_extra_bytes",
|
"add_extra_bytes",
|
||||||
);
|
);
|
||||||
|
|
||||||
env.call_alloc(number_of_bytes, layout.alignment_bytes(env.ptr_bytes))
|
env.call_alloc(number_of_bytes, alignment_bytes)
|
||||||
};
|
};
|
||||||
|
|
||||||
// We must return a pointer to the first element:
|
// We must return a pointer to the first element:
|
||||||
|
@ -2640,6 +2684,13 @@ fn build_switch_ir<'a, 'ctx, 'env>(
|
||||||
Layout::Union(variant) => {
|
Layout::Union(variant) => {
|
||||||
cond_layout = Layout::Builtin(Builtin::Int64);
|
cond_layout = Layout::Builtin(Builtin::Int64);
|
||||||
|
|
||||||
|
/*
|
||||||
|
cond_layout = match variant {
|
||||||
|
UnionLayout::NonRecursive(_) => Layout::Builtin(Builtin::Int16),
|
||||||
|
_ => Layout::Builtin(Builtin::Int64),
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
extract_tag_discriminant(env, parent, variant, cond_value)
|
extract_tag_discriminant(env, parent, variant, cond_value)
|
||||||
}
|
}
|
||||||
Layout::Builtin(_) => cond_value.into_int_value(),
|
Layout::Builtin(_) => cond_value.into_int_value(),
|
||||||
|
|
|
@ -741,7 +741,6 @@ pub fn list_map<'a, 'ctx, 'env>(
|
||||||
element_layout: &Layout<'a>,
|
element_layout: &Layout<'a>,
|
||||||
return_layout: &Layout<'a>,
|
return_layout: &Layout<'a>,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
dbg!(return_layout, layout_width(env, return_layout));
|
|
||||||
call_bitcode_fn_returns_list(
|
call_bitcode_fn_returns_list(
|
||||||
env,
|
env,
|
||||||
&[
|
&[
|
||||||
|
@ -1114,7 +1113,9 @@ pub fn allocate_list<'a, 'ctx, 'env>(
|
||||||
// we assume that the list is indeed used (dead variables are eliminated)
|
// we assume that the list is indeed used (dead variables are eliminated)
|
||||||
let rc1 = crate::llvm::refcounting::refcount_1(ctx, env.ptr_bytes);
|
let rc1 = crate::llvm::refcounting::refcount_1(ctx, env.ptr_bytes);
|
||||||
|
|
||||||
allocate_with_refcount_help(env, elem_layout, number_of_data_bytes, rc1)
|
let basic_type = basic_type_from_layout(env, elem_layout);
|
||||||
|
let alignment_bytes = elem_layout.alignment_bytes(env.ptr_bytes);
|
||||||
|
allocate_with_refcount_help(env, basic_type, alignment_bytes, number_of_data_bytes, rc1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn store_list<'a, 'ctx, 'env>(
|
pub fn store_list<'a, 'ctx, 'env>(
|
||||||
|
|
|
@ -71,52 +71,6 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn basic_type_from_layout_old<'a, 'ctx, 'env>(
|
|
||||||
env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
|
|
||||||
layout: &Layout<'_>,
|
|
||||||
) -> BasicTypeEnum<'ctx> {
|
|
||||||
use Layout::*;
|
|
||||||
|
|
||||||
match layout {
|
|
||||||
Closure(_args, closure_layout, _ret_layout) => {
|
|
||||||
let closure_data_layout = closure_layout.runtime_representation();
|
|
||||||
basic_type_from_layout(env, &closure_data_layout)
|
|
||||||
}
|
|
||||||
Struct(sorted_fields) => basic_type_from_record(env, sorted_fields),
|
|
||||||
Union(variant) => {
|
|
||||||
use UnionLayout::*;
|
|
||||||
match variant {
|
|
||||||
Recursive(tags)
|
|
||||||
| NullableWrapped {
|
|
||||||
other_tags: tags, ..
|
|
||||||
} => {
|
|
||||||
let block = block_of_memory_slices(env.context, tags, env.ptr_bytes);
|
|
||||||
block.ptr_type(AddressSpace::Generic).into()
|
|
||||||
}
|
|
||||||
NullableUnwrapped { other_fields, .. } => {
|
|
||||||
let block =
|
|
||||||
block_of_memory_slices(env.context, &[&other_fields[1..]], env.ptr_bytes);
|
|
||||||
block.ptr_type(AddressSpace::Generic).into()
|
|
||||||
}
|
|
||||||
NonNullableUnwrapped(fields) => {
|
|
||||||
let block = block_of_memory_slices(env.context, &[fields], env.ptr_bytes);
|
|
||||||
block.ptr_type(AddressSpace::Generic).into()
|
|
||||||
}
|
|
||||||
NonRecursive(_) => block_of_memory(env.context, layout, env.ptr_bytes),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RecursivePointer => {
|
|
||||||
// TODO make this dynamic
|
|
||||||
env.context
|
|
||||||
.i64_type()
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum()
|
|
||||||
}
|
|
||||||
|
|
||||||
Builtin(builtin) => basic_type_from_builtin(env, builtin),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn basic_type_from_builtin<'a, 'ctx, 'env>(
|
pub fn basic_type_from_builtin<'a, 'ctx, 'env>(
|
||||||
env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
|
env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
|
||||||
builtin: &Builtin<'_>,
|
builtin: &Builtin<'_>,
|
||||||
|
|
|
@ -4,9 +4,7 @@ use crate::llvm::build::{
|
||||||
LLVM_SADD_WITH_OVERFLOW_I64, TAG_DATA_INDEX, TAG_ID_INDEX,
|
LLVM_SADD_WITH_OVERFLOW_I64, TAG_DATA_INDEX, TAG_ID_INDEX,
|
||||||
};
|
};
|
||||||
use crate::llvm::build_list::{incrementing_elem_loop, list_len, load_list};
|
use crate::llvm::build_list::{incrementing_elem_loop, list_len, load_list};
|
||||||
use crate::llvm::convert::{
|
use crate::llvm::convert::{basic_type_from_layout, block_of_memory_slices, ptr_int};
|
||||||
basic_type_from_layout, block_of_memory, block_of_memory_slices, ptr_int,
|
|
||||||
};
|
|
||||||
use bumpalo::collections::Vec;
|
use bumpalo::collections::Vec;
|
||||||
use inkwell::basic_block::BasicBlock;
|
use inkwell::basic_block::BasicBlock;
|
||||||
use inkwell::context::Context;
|
use inkwell::context::Context;
|
||||||
|
|
|
@ -1007,10 +1007,10 @@ fn applied_tag_function_result() {
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocList::from_slice(&[
|
RocList::from_slice(&[
|
||||||
(1, RocStr::from_slice("a".as_bytes())),
|
(RocStr::from_slice("a".as_bytes())),
|
||||||
(1, RocStr::from_slice("b".as_bytes()))
|
(RocStr::from_slice("b".as_bytes()))
|
||||||
]),
|
]),
|
||||||
RocList<(i64, RocStr)>
|
RocList<RocStr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue