mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Make sure to memcpy with correct size and alignments
This commit is contained in:
parent
57019d5b78
commit
ea6330b48b
2 changed files with 48 additions and 14 deletions
|
@ -1659,10 +1659,24 @@ fn build_tag<'a, 'ctx>(
|
|||
// let data_layout_repr = LayoutRepr::Struct(tags[tag_id as usize]);
|
||||
// let data = RocStruct::build(env, layout_interner, data_layout_repr, scope, arguments);
|
||||
let data = legacy_build_struct_while_debugging(env, layout_interner, scope, arguments);
|
||||
let data_alloca = create_entry_block_alloca(
|
||||
env,
|
||||
parent,
|
||||
data.get_type().into(),
|
||||
"non_recursive_data_alloca",
|
||||
);
|
||||
env.builder.build_store(data_alloca, data);
|
||||
|
||||
let roc_union =
|
||||
RocUnion::tagged_from_slices(layout_interner, env.context, tags, env.target_info);
|
||||
let value = roc_union.as_struct_value(env, RocStruct::ByValue(data), Some(tag_id as _));
|
||||
let data_layout = LayoutRepr::Struct(tags[tag_id as usize]);
|
||||
let value = roc_union.as_struct_value(
|
||||
env,
|
||||
layout_interner,
|
||||
RocStruct::ByReference(data_alloca),
|
||||
data_layout,
|
||||
Some(tag_id as _),
|
||||
);
|
||||
|
||||
let alloca = create_entry_block_alloca(
|
||||
env,
|
||||
|
@ -1795,8 +1809,15 @@ fn build_tag<'a, 'ctx>(
|
|||
// let data_layout_repr = LayoutRepr::Struct(other_fields);
|
||||
// let data = RocStruct::build(env, layout_interner, data_layout_repr, scope, arguments);
|
||||
let data = legacy_build_struct_while_debugging(env, layout_interner, scope, arguments);
|
||||
let data_layout = LayoutRepr::Struct(other_fields);
|
||||
|
||||
let value = roc_union.as_struct_value(env, RocStruct::ByValue(data), None);
|
||||
let value = roc_union.as_struct_value(
|
||||
env,
|
||||
layout_interner,
|
||||
RocStruct::ByValue(data),
|
||||
data_layout,
|
||||
None,
|
||||
);
|
||||
|
||||
env.builder.build_store(data_ptr, value);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ use inkwell::types::{BasicType, BasicTypeEnum, FloatType, IntType, StructType};
|
|||
use inkwell::values::StructValue;
|
||||
use inkwell::AddressSpace;
|
||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||
use roc_error_macros::internal_error;
|
||||
use roc_mono::layout::{
|
||||
round_up_to_alignment, Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, STLayoutInterner,
|
||||
UnionLayout,
|
||||
|
@ -401,7 +402,9 @@ impl<'ctx> RocUnion<'ctx> {
|
|||
pub fn as_struct_value<'a, 'env>(
|
||||
&self,
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_interner: &STLayoutInterner<'a>,
|
||||
data: RocStruct<'ctx>,
|
||||
data_layout: LayoutRepr<'a>,
|
||||
tag_id: Option<usize>,
|
||||
) -> StructValue<'ctx> {
|
||||
debug_assert_eq!(tag_id.is_some(), self.tag_type.is_some());
|
||||
|
@ -430,22 +433,32 @@ impl<'ctx> RocUnion<'ctx> {
|
|||
);
|
||||
env.builder.build_store(cast_pointer, value);
|
||||
}
|
||||
RocStruct::ByReference(ptr) => {
|
||||
let cast_pointer =
|
||||
env.builder
|
||||
.build_pointer_cast(data_buffer, ptr.get_type(), "to_data_ptr");
|
||||
RocStruct::ByReference(payload_data_ptr) => {
|
||||
let cast_tag_pointer = env.builder.build_pointer_cast(
|
||||
data_buffer,
|
||||
payload_data_ptr.get_type(),
|
||||
"to_data_ptr",
|
||||
);
|
||||
|
||||
env.builder
|
||||
let (payload_stack_size, payload_align) =
|
||||
data_layout.stack_size_and_alignment(layout_interner, env.target_info);
|
||||
|
||||
if payload_stack_size > 0 {
|
||||
let bytes_to_memcpy = env
|
||||
.context
|
||||
.i32_type()
|
||||
.const_int(payload_stack_size as _, false);
|
||||
|
||||
env.builder
|
||||
.build_memcpy(
|
||||
cast_pointer,
|
||||
cast_tag_pointer,
|
||||
self.data_align,
|
||||
ptr,
|
||||
self.data_align,
|
||||
env.context
|
||||
.i32_type()
|
||||
.const_int(self.data_width as _, false),
|
||||
payload_data_ptr,
|
||||
payload_align,
|
||||
bytes_to_memcpy
|
||||
)
|
||||
.expect("memcpy invariants must have been upheld");
|
||||
.unwrap_or_else(|e|internal_error!( "memcpy invariants must have been upheld: {e:?}. Union data align={}, source data align={}.", self.data_align, payload_align));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue