add LayoutRepr::Ptr

This commit is contained in:
Folkert 2023-06-18 15:44:40 +02:00
parent a9f7961b52
commit 17512873e8
No known key found for this signature in database
GPG Key ID: 1F17F6FFD112B97C
18 changed files with 62 additions and 8 deletions

View File

@ -1589,13 +1589,14 @@ fn layout_spec_help<'a>(
}
}
Boxed(inner_layout) => {
Ptr(inner_layout) | Boxed(inner_layout) => {
let inner_type =
layout_spec_help(env, builder, interner, interner.get_repr(inner_layout))?;
let cell_type = builder.add_heap_cell_type();
builder.add_tuple_type(&[cell_type, inner_type])
}
// TODO(recursive-layouts): update once we have recursive pointer loops
RecursivePointer(union_layout) => match interner.get_repr(union_layout) {
LayoutRepr::Union(union_layout) => {

View File

@ -4385,6 +4385,7 @@ macro_rules! single_register_layouts {
macro_rules! pointer_layouts {
() => {
LayoutRepr::Boxed(_)
| LayoutRepr::Ptr(_)
| LayoutRepr::RecursivePointer(_)
| LayoutRepr::Union(
UnionLayout::Recursive(_)

View File

@ -826,7 +826,7 @@ impl<
self.copy_to_stack_offset(buf, size, from_offset, to_offset)
}
LayoutRepr::RecursivePointer(_) | LayoutRepr::Boxed(_) | LayoutRepr::Union(_) => {
pointer_layouts!() => {
// like a 64-bit integer
debug_assert_eq!(to_offset % 8, 0);
let reg = self.load_to_general_reg(buf, sym);

View File

@ -120,7 +120,7 @@ impl<'a> LlvmAlignment<'a> for LayoutRepr<'a> {
.llvm_alignment_bytes(interner),
Builtin(builtin) => builtin.llvm_alignment_bytes(interner),
RecursivePointer(_) => interner.target_info().ptr_width() as u32,
Boxed(_) => interner.target_info().ptr_width() as u32,
Ptr(_) | Boxed(_) => interner.target_info().ptr_width() as u32,
}
}
}

View File

@ -185,7 +185,7 @@ fn build_eq<'a, 'ctx>(
rhs_val,
),
LayoutRepr::Boxed(inner_layout) => build_box_eq(
LayoutRepr::Ptr(inner_layout) | LayoutRepr::Boxed(inner_layout) => build_box_eq(
env,
layout_interner,
layout_ids,
@ -385,7 +385,7 @@ fn build_neq<'a, 'ctx>(
result.into()
}
LayoutRepr::Boxed(inner_layout) => {
LayoutRepr::Ptr(inner_layout) | LayoutRepr::Boxed(inner_layout) => {
let is_equal = build_box_eq(
env,
layout_interner,

View File

@ -40,6 +40,13 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>(
inner_type.ptr_type(AddressSpace::default()).into()
}
Union(union_layout) => basic_type_from_union_layout(env, layout_interner, &union_layout),
Ptr(_) => env
.context
.i64_type()
.ptr_type(AddressSpace::default())
.as_basic_type_enum(),
RecursivePointer(_) => env
.context
.i64_type()

View File

@ -390,6 +390,10 @@ fn build_clone<'a, 'ctx>(
)
}
LayoutRepr::Ptr(_) => {
unreachable!("for internal use only")
}
LayoutRepr::RecursivePointer(rec_layout) => {
let layout = rec_layout;

View File

@ -537,6 +537,12 @@ fn modify_refcount_layout_build_function<'a, 'ctx>(
Some(function)
}
Ptr(_inner) => {
debug_assert_eq!(true, false);
None
}
Union(variant) => {
use UnionLayout::*;

View File

@ -98,6 +98,7 @@ impl WasmLayout {
| NullableUnwrapped { .. },
)
| LayoutRepr::Boxed(_)
| LayoutRepr::Ptr(_)
| LayoutRepr::RecursivePointer(_) => Self::Primitive(PTR_TYPE, PTR_SIZE),
}
}

View File

@ -2030,7 +2030,8 @@ impl<'a> LowLevelCall<'a> {
| LayoutRepr::Struct { .. }
| LayoutRepr::Union(_)
| LayoutRepr::LambdaSet(_)
| LayoutRepr::Boxed(_) => {
| LayoutRepr::Boxed(_)
| LayoutRepr::Ptr(_) => {
// Don't want Zig calling convention here, we're calling internal Roc functions
backend
.storage

View File

@ -38,6 +38,7 @@ pub fn eq_generic<'a>(
Struct(field_layouts) => eq_struct(root, ident_ids, ctx, layout_interner, field_layouts),
Union(union_layout) => eq_tag_union(root, ident_ids, ctx, layout_interner, union_layout),
Boxed(inner_layout) => eq_boxed(root, ident_ids, ctx, layout_interner, inner_layout),
Ptr(inner_layout) => eq_boxed(root, ident_ids, ctx, layout_interner, inner_layout),
LambdaSet(_) => unreachable!("`==` is not defined on functions"),
RecursivePointer(_) => {
unreachable!(

View File

@ -577,6 +577,11 @@ impl<'a> CodeGenHelp<'a> {
LayoutRepr::Boxed(inner)
}
LayoutRepr::Ptr(inner) => {
let inner = self.replace_rec_ptr(ctx, layout_interner, inner);
LayoutRepr::Ptr(inner)
}
LayoutRepr::LambdaSet(lambda_set) => {
return self.replace_rec_ptr(ctx, layout_interner, lambda_set.representation)
}
@ -844,5 +849,6 @@ fn layout_needs_helper_proc<'a>(
LayoutRepr::LambdaSet(_) => true,
LayoutRepr::RecursivePointer(_) => false,
LayoutRepr::Boxed(_) => true,
LayoutRepr::Ptr(_) => false,
}
}

View File

@ -239,6 +239,9 @@ pub fn refcount_generic<'a>(
inner_layout,
structure,
),
LayoutRepr::Ptr(_) => {
unreachable!("We should never call a refcounting helper on a Ptr layout directly")
}
}
}

View File

@ -9866,6 +9866,9 @@ where
LayoutRepr::Boxed(boxed) => {
stack.push(layout_interner.get(boxed));
}
LayoutRepr::Ptr(inner) => {
stack.push(layout_interner.get(inner));
}
LayoutRepr::Union(union_layout) => match union_layout {
UnionLayout::NonRecursive(tags) => {
for in_layout in tags.iter().flat_map(|e| e.iter()) {

View File

@ -675,6 +675,7 @@ pub enum LayoutRepr<'a> {
Builtin(Builtin<'a>),
Struct(&'a [InLayout<'a>]),
Boxed(InLayout<'a>),
Ptr(InLayout<'a>),
Union(UnionLayout<'a>),
LambdaSet(LambdaSet<'a>),
RecursivePointer(InLayout<'a>),
@ -2555,7 +2556,7 @@ impl<'a> LayoutRepr<'a> {
LambdaSet(lambda_set) => interner
.get_repr(lambda_set.runtime_representation())
.safe_to_memcpy(interner),
Boxed(_) | RecursivePointer(_) => {
Boxed(_) | Ptr(_) | RecursivePointer(_) => {
// We cannot memcpy pointers, because then we would have the same pointer in multiple places!
false
}
@ -2646,6 +2647,7 @@ impl<'a> LayoutRepr<'a> {
.stack_size_without_alignment(interner),
RecursivePointer(_) => interner.target_info().ptr_width() as u32,
Boxed(_) => interner.target_info().ptr_width() as u32,
Ptr(_) => interner.target_info().ptr_width() as u32,
}
}
@ -2699,6 +2701,7 @@ impl<'a> LayoutRepr<'a> {
Builtin(builtin) => builtin.alignment_bytes(interner.target_info()),
RecursivePointer(_) => interner.target_info().ptr_width() as u32,
Boxed(_) => interner.target_info().ptr_width() as u32,
Ptr(_) => interner.target_info().ptr_width() as u32,
}
}
@ -2723,6 +2726,7 @@ impl<'a> LayoutRepr<'a> {
ptr_width,
interner.get_repr(*inner).alignment_bytes(interner),
),
Ptr(inner) => interner.get_repr(*inner).alignment_bytes(interner),
}
}
@ -2776,6 +2780,7 @@ impl<'a> LayoutRepr<'a> {
.contains_refcounted(interner),
RecursivePointer(_) => true,
Boxed(_) => true,
Ptr(inner) => interner.get_repr(*inner).contains_refcounted(interner),
}
}
@ -2831,7 +2836,7 @@ impl<'a> LayoutRepr<'a> {
}
},
LambdaSet(_) => return true,
Boxed(_) => {
Boxed(_) | Ptr(_) => {
// If there's any layer of indirection (behind a pointer), then it doesn't vary!
}
RecursivePointer(_) => {

View File

@ -350,6 +350,10 @@ pub trait LayoutInterner<'a>: Sized {
.text("Boxed(")
.append(self.to_doc(inner, alloc, seen_rec, parens))
.append(")"),
Ptr(inner) => alloc
.text("Ptr(")
.append(self.to_doc(inner, alloc, seen_rec, parens))
.append(")"),
}
}
@ -1108,6 +1112,7 @@ mod reify {
LayoutRepr::Struct(reify_layout_slice(arena, interner, slot, field_layouts))
}
LayoutRepr::Boxed(lay) => LayoutRepr::Boxed(reify_layout(arena, interner, slot, lay)),
LayoutRepr::Ptr(lay) => LayoutRepr::Ptr(reify_layout(arena, interner, slot, lay)),
LayoutRepr::Union(un) => LayoutRepr::Union(reify_union(arena, interner, slot, un)),
LayoutRepr::LambdaSet(ls) => {
LayoutRepr::LambdaSet(reify_lambda_set(arena, interner, slot, ls))
@ -1312,6 +1317,7 @@ mod equiv {
equiv_fields!(fl1, fl2)
}
(Boxed(b1), Boxed(b2)) => stack.push((b1, b2)),
(Ptr(b1), Ptr(b2)) => stack.push((b1, b2)),
(Union(u1), Union(u2)) => {
use UnionLayout::*;
match (u1, u2) {
@ -1432,6 +1438,7 @@ pub mod dbg_deep {
.field("fields", &DbgFields(self.0, field_layouts))
.finish(),
LayoutRepr::Boxed(b) => f.debug_tuple("Boxed").field(&Dbg(self.0, *b)).finish(),
LayoutRepr::Ptr(b) => f.debug_tuple("Ptr").field(&Dbg(self.0, *b)).finish(),
LayoutRepr::Union(un) => f
.debug_tuple("Union")
.field(&DbgUnion(self.0, *un))
@ -1605,6 +1612,7 @@ pub mod dbg_stable {
.field("fields", &DbgFields(self.0, field_layouts))
.finish(),
LayoutRepr::Boxed(b) => f.debug_tuple("Boxed").field(&Dbg(self.0, *b)).finish(),
LayoutRepr::Ptr(b) => f.debug_tuple("Ptr").field(&Dbg(self.0, *b)).finish(),
LayoutRepr::Union(un) => f
.debug_tuple("Union")
.field(&DbgUnion(self.0, *un))

View File

@ -2085,6 +2085,7 @@ fn tag_union_type_from_layout<'a>(
},
}
}
LayoutRepr::Ptr(_) => unreachable!("Ptr values are never publicly exposed"),
LayoutRepr::Boxed(elem_layout) => {
let (tag_name, payload_fields) =
single_tag_payload_fields(env, union_tags, subs, layout, &[elem_layout], types);

View File

@ -534,6 +534,9 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
LayoutRepr::RecursivePointer(_) => {
unreachable!("RecursivePointers can only be inside structures")
}
LayoutRepr::Ptr(_) => {
unreachable!("Ptr will never be visible to users")
}
LayoutRepr::LambdaSet(_) => OPAQUE_FUNCTION,
LayoutRepr::Boxed(_) => {
let size = env.layout_cache.interner.stack_size(layout);
@ -918,6 +921,9 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
(_, LayoutRepr::Boxed(_)) => {
unreachable!("Box layouts can only be behind a `Box.Box` application")
}
(_, LayoutRepr::Ptr(_)) => {
unreachable!("Ptr layouts are never available in user code")
}
};
apply_newtypes(env, newtype_containers.into_bump_slice(), expr)
}