mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Wrap layouts in a LayoutRepr
constructor
Part 1 of support semantic layout representations.
This commit is contained in:
parent
c2d2bd4bb9
commit
c3eeb5e2cc
32 changed files with 1254 additions and 1021 deletions
|
@ -18,7 +18,7 @@ use inkwell::AddressSpace;
|
|||
use roc_error_macros::internal_error;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_mono::layout::{
|
||||
Builtin, InLayout, LambdaSet, Layout, LayoutIds, LayoutInterner, STLayoutInterner,
|
||||
Builtin, InLayout, LambdaSet, LayoutIds, LayoutInterner, LayoutRepr, STLayoutInterner,
|
||||
};
|
||||
|
||||
use super::build::{create_entry_block_alloca, BuilderExt};
|
||||
|
@ -610,8 +610,8 @@ pub fn build_compare_wrapper<'a, 'ctx>(
|
|||
|
||||
let closure_data_repr = closure_data_layout.runtime_representation();
|
||||
|
||||
let arguments_cast = match layout_interner.get(closure_data_repr) {
|
||||
Layout::Struct {
|
||||
let arguments_cast = match layout_interner.get(closure_data_repr).repr {
|
||||
LayoutRepr::Struct {
|
||||
field_layouts: &[], ..
|
||||
} => {
|
||||
// nothing to add
|
||||
|
|
|
@ -43,7 +43,7 @@ use roc_mono::ir::{
|
|||
ListLiteralElement, ModifyRc, OptLevel, ProcLayout, SingleEntryPoint,
|
||||
};
|
||||
use roc_mono::layout::{
|
||||
Builtin, InLayout, LambdaName, LambdaSet, Layout, LayoutIds, LayoutInterner, Niche,
|
||||
Builtin, InLayout, LambdaName, LambdaSet, Layout, LayoutIds, LayoutInterner, LayoutRepr, Niche,
|
||||
RawFunctionLayout, STLayoutInterner, TagIdIntType, UnionLayout,
|
||||
};
|
||||
use roc_std::RocDec;
|
||||
|
@ -783,13 +783,13 @@ pub fn build_exp_literal<'a, 'ctx>(
|
|||
use roc_mono::ir::Literal::*;
|
||||
|
||||
match literal {
|
||||
Int(bytes) => match layout_interner.get(layout) {
|
||||
Layout::Builtin(Builtin::Bool) => env
|
||||
Int(bytes) => match layout_interner.get(layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Bool) => env
|
||||
.context
|
||||
.bool_type()
|
||||
.const_int(i128::from_ne_bytes(*bytes) as u64, false)
|
||||
.into(),
|
||||
Layout::Builtin(Builtin::Int(int_width)) => {
|
||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
|
||||
int_with_precision(env, i128::from_ne_bytes(*bytes), int_width).into()
|
||||
}
|
||||
_ => panic!("Invalid layout for int literal = {:?}", layout),
|
||||
|
@ -797,8 +797,8 @@ pub fn build_exp_literal<'a, 'ctx>(
|
|||
|
||||
U128(bytes) => const_u128(env, u128::from_ne_bytes(*bytes)).into(),
|
||||
|
||||
Float(float) => match layout_interner.get(layout) {
|
||||
Layout::Builtin(Builtin::Float(float_width)) => {
|
||||
Float(float) => match layout_interner.get(layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
||||
float_with_precision(env, *float, float_width)
|
||||
}
|
||||
_ => panic!("Invalid layout for float literal = {:?}", layout),
|
||||
|
@ -1178,8 +1178,8 @@ pub fn build_exp_expr<'a, 'ctx>(
|
|||
let tag_ptr = tag_ptr.into_pointer_value();
|
||||
|
||||
// reset is only generated for union values
|
||||
let union_layout = match layout_interner.get(layout) {
|
||||
Layout::Union(ul) => ul,
|
||||
let union_layout = match layout_interner.get(layout).repr {
|
||||
LayoutRepr::Union(ul) => ul,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -1285,15 +1285,16 @@ pub fn build_exp_expr<'a, 'ctx>(
|
|||
} => {
|
||||
let (value, layout) = load_symbol_and_layout(scope, structure);
|
||||
|
||||
let layout = if let Layout::LambdaSet(lambda_set) = layout_interner.get(layout) {
|
||||
let layout = if let LayoutRepr::LambdaSet(lambda_set) = layout_interner.get(layout).repr
|
||||
{
|
||||
lambda_set.runtime_representation()
|
||||
} else {
|
||||
layout
|
||||
};
|
||||
|
||||
// extract field from a record
|
||||
match (value, layout_interner.get(layout)) {
|
||||
(StructValue(argument), Layout::Struct { field_layouts, .. }) => {
|
||||
match (value, layout_interner.get(layout).repr) {
|
||||
(StructValue(argument), LayoutRepr::Struct { field_layouts, .. }) => {
|
||||
debug_assert!(!field_layouts.is_empty());
|
||||
|
||||
let field_value = env
|
||||
|
@ -1586,7 +1587,7 @@ fn build_tag_field_value<'a, 'ctx>(
|
|||
value: BasicValueEnum<'ctx>,
|
||||
tag_field_layout: InLayout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
if let Layout::RecursivePointer(_) = layout_interner.get(tag_field_layout) {
|
||||
if let LayoutRepr::RecursivePointer(_) = layout_interner.get(tag_field_layout).repr {
|
||||
debug_assert!(value.is_pointer_value());
|
||||
|
||||
// we store recursive pointers as `i64*`
|
||||
|
@ -1741,7 +1742,9 @@ fn build_tag<'a, 'ctx>(
|
|||
use std::cmp::Ordering::*;
|
||||
match tag_id.cmp(&(*nullable_id as _)) {
|
||||
Equal => {
|
||||
let layout = layout_interner.insert(Layout::Union(*union_layout));
|
||||
let layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(*union_layout),
|
||||
});
|
||||
|
||||
return basic_type_from_layout(env, layout_interner, layout)
|
||||
.into_pointer_type()
|
||||
|
@ -2505,8 +2508,8 @@ pub fn build_exp_stmt<'a, 'ctx>(
|
|||
|
||||
for (symbol, expr, layout) in queue {
|
||||
debug_assert!(!matches!(
|
||||
layout_interner.get(*layout),
|
||||
Layout::RecursivePointer(_)
|
||||
layout_interner.get(*layout).repr,
|
||||
LayoutRepr::RecursivePointer(_)
|
||||
));
|
||||
|
||||
let val = build_exp_expr(
|
||||
|
@ -2805,9 +2808,10 @@ pub fn build_exp_stmt<'a, 'ctx>(
|
|||
DecRef(symbol) => {
|
||||
let (value, layout) = load_symbol_and_layout(scope, symbol);
|
||||
|
||||
match layout_interner.get(layout) {
|
||||
Layout::Builtin(Builtin::Str) => todo!(),
|
||||
Layout::Builtin(Builtin::List(element_layout)) => {
|
||||
let lay = layout_interner.get(layout);
|
||||
match lay.repr {
|
||||
LayoutRepr::Builtin(Builtin::Str) => todo!(),
|
||||
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
|
||||
debug_assert!(value.is_struct_value());
|
||||
let element_layout = layout_interner.get(element_layout);
|
||||
let alignment =
|
||||
|
@ -2816,7 +2820,7 @@ pub fn build_exp_stmt<'a, 'ctx>(
|
|||
build_list::decref(env, value.into_struct_value(), alignment);
|
||||
}
|
||||
|
||||
lay if lay.is_refcounted() => {
|
||||
_ if lay.is_refcounted() => {
|
||||
if value.is_pointer_value() {
|
||||
let value_ptr = value.into_pointer_value();
|
||||
|
||||
|
@ -3388,8 +3392,8 @@ fn build_switch_ir<'a, 'ctx>(
|
|||
let cont_block = context.append_basic_block(parent, "cont");
|
||||
|
||||
// Build the condition
|
||||
let cond = match layout_interner.get(cond_layout) {
|
||||
Layout::Builtin(Builtin::Float(float_width)) => {
|
||||
let cond = match layout_interner.get(cond_layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
||||
// float matches are done on the bit pattern
|
||||
cond_layout = Layout::float_width(float_width);
|
||||
|
||||
|
@ -3402,19 +3406,19 @@ fn build_switch_ir<'a, 'ctx>(
|
|||
.build_bitcast(cond_value, int_type, "")
|
||||
.into_int_value()
|
||||
}
|
||||
Layout::Union(variant) => {
|
||||
LayoutRepr::Union(variant) => {
|
||||
cond_layout = variant.tag_id_layout();
|
||||
|
||||
get_tag_id(env, layout_interner, parent, &variant, cond_value)
|
||||
}
|
||||
Layout::Builtin(_) => cond_value.into_int_value(),
|
||||
LayoutRepr::Builtin(_) => cond_value.into_int_value(),
|
||||
other => todo!("Build switch value from layout: {:?}", other),
|
||||
};
|
||||
|
||||
// Build the cases
|
||||
let mut incoming = Vec::with_capacity_in(branches.len(), arena);
|
||||
|
||||
if let Layout::Builtin(Builtin::Bool) = layout_interner.get(cond_layout) {
|
||||
if let LayoutRepr::Builtin(Builtin::Bool) = layout_interner.get(cond_layout).repr {
|
||||
match (branches, default_branch) {
|
||||
([(0, _, false_branch)], true_branch) | ([(1, _, true_branch)], false_branch) => {
|
||||
let then_block = context.append_basic_block(parent, "then_block");
|
||||
|
@ -3822,8 +3826,8 @@ fn expose_function_to_host_help_c_abi_gen_test<'a, 'ctx>(
|
|||
// the C and Fast calling conventions agree
|
||||
arguments_for_call.push(*arg);
|
||||
} else {
|
||||
match layout_interner.get(*layout) {
|
||||
Layout::Builtin(Builtin::List(_)) => {
|
||||
match layout_interner.get(*layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::List(_)) => {
|
||||
let list_type = arg_type
|
||||
.into_pointer_type()
|
||||
.get_element_type()
|
||||
|
@ -3961,7 +3965,7 @@ fn expose_function_to_host_help_c_abi_v2<'a, 'ctx>(
|
|||
};
|
||||
|
||||
for (i, layout) in arguments.iter().enumerate() {
|
||||
if let Layout::Builtin(Builtin::Str) = layout_interner.get(*layout) {
|
||||
if let LayoutRepr::Builtin(Builtin::Str) = layout_interner.get(*layout).repr {
|
||||
// Indicate to LLVM that this argument is semantically passed by-value
|
||||
// even though technically (because of its size) it is passed by-reference
|
||||
let byval_attribute_id = Attribute::get_named_enum_kind_id("byval");
|
||||
|
@ -4061,8 +4065,10 @@ fn expose_function_to_host_help_c_abi_v2<'a, 'ctx>(
|
|||
env.target_info.architecture,
|
||||
roc_target::Architecture::X86_32 | roc_target::Architecture::X86_64
|
||||
) {
|
||||
let c_abi_type = match layout_interner.get(*layout) {
|
||||
Layout::Builtin(Builtin::Str | Builtin::List(_)) => c_abi_roc_str_type,
|
||||
let c_abi_type = match layout_interner.get(*layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Str | Builtin::List(_)) => {
|
||||
c_abi_roc_str_type
|
||||
}
|
||||
_ => todo!("figure out what the C type is"),
|
||||
};
|
||||
|
||||
|
@ -5628,8 +5634,8 @@ fn to_cc_type<'a, 'ctx>(
|
|||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
layout: InLayout<'a>,
|
||||
) -> BasicTypeEnum<'ctx> {
|
||||
match layout_interner.runtime_representation(layout) {
|
||||
Layout::Builtin(builtin) => to_cc_type_builtin(env, &builtin),
|
||||
match layout_interner.runtime_representation(layout).repr {
|
||||
LayoutRepr::Builtin(builtin) => to_cc_type_builtin(env, &builtin),
|
||||
_ => {
|
||||
// TODO this is almost certainly incorrect for bigger structs
|
||||
basic_type_from_layout(env, layout_interner, layout)
|
||||
|
@ -5675,8 +5681,8 @@ impl RocReturn {
|
|||
target_info: TargetInfo,
|
||||
layout: InLayout,
|
||||
) -> bool {
|
||||
match interner.get(layout) {
|
||||
Layout::Builtin(builtin) => {
|
||||
match interner.get(layout).repr {
|
||||
LayoutRepr::Builtin(builtin) => {
|
||||
use Builtin::*;
|
||||
|
||||
match target_info.ptr_width() {
|
||||
|
@ -5688,8 +5694,8 @@ impl RocReturn {
|
|||
}
|
||||
}
|
||||
}
|
||||
Layout::Union(UnionLayout::NonRecursive(_)) => true,
|
||||
Layout::LambdaSet(lambda_set) => RocReturn::roc_return_by_pointer(
|
||||
LayoutRepr::Union(UnionLayout::NonRecursive(_)) => true,
|
||||
LayoutRepr::LambdaSet(lambda_set) => RocReturn::roc_return_by_pointer(
|
||||
interner,
|
||||
target_info,
|
||||
lambda_set.runtime_representation(),
|
||||
|
|
|
@ -11,7 +11,7 @@ use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
|||
use roc_error_macros::internal_error;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_mono::layout::{
|
||||
Builtin, InLayout, Layout, LayoutIds, LayoutInterner, STLayoutInterner, UnionLayout,
|
||||
Builtin, InLayout, Layout, LayoutIds, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout,
|
||||
};
|
||||
|
||||
use super::build::{load_roc_value, use_roc_value, BuilderExt};
|
||||
|
@ -154,8 +154,8 @@ fn build_eq<'a, 'ctx>(
|
|||
);
|
||||
}
|
||||
|
||||
match layout_interner.get(*lhs_layout) {
|
||||
Layout::Builtin(builtin) => build_eq_builtin(
|
||||
match layout_interner.get(*lhs_layout).repr {
|
||||
LayoutRepr::Builtin(builtin) => build_eq_builtin(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
|
@ -165,7 +165,7 @@ fn build_eq<'a, 'ctx>(
|
|||
&builtin,
|
||||
),
|
||||
|
||||
Layout::Struct { field_layouts, .. } => build_struct_eq(
|
||||
LayoutRepr::Struct { field_layouts, .. } => build_struct_eq(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
|
@ -175,9 +175,9 @@ fn build_eq<'a, 'ctx>(
|
|||
rhs_val.into_struct_value(),
|
||||
),
|
||||
|
||||
Layout::LambdaSet(_) => unreachable!("cannot compare closures"),
|
||||
LayoutRepr::LambdaSet(_) => unreachable!("cannot compare closures"),
|
||||
|
||||
Layout::Union(union_layout) => build_tag_eq(
|
||||
LayoutRepr::Union(union_layout) => build_tag_eq(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
|
@ -187,7 +187,7 @@ fn build_eq<'a, 'ctx>(
|
|||
rhs_val,
|
||||
),
|
||||
|
||||
Layout::Boxed(inner_layout) => build_box_eq(
|
||||
LayoutRepr::Boxed(inner_layout) => build_box_eq(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
|
@ -197,7 +197,7 @@ fn build_eq<'a, 'ctx>(
|
|||
rhs_val,
|
||||
),
|
||||
|
||||
Layout::RecursivePointer(rec_layout) => {
|
||||
LayoutRepr::RecursivePointer(rec_layout) => {
|
||||
let layout = rec_layout;
|
||||
|
||||
let bt = basic_type_from_layout(env, layout_interner, layout);
|
||||
|
@ -215,8 +215,8 @@ fn build_eq<'a, 'ctx>(
|
|||
"i64_to_opaque",
|
||||
);
|
||||
|
||||
let union_layout = match layout_interner.get(rec_layout) {
|
||||
Layout::Union(union_layout) => {
|
||||
let union_layout = match layout_interner.get(rec_layout).repr {
|
||||
LayoutRepr::Union(union_layout) => {
|
||||
debug_assert!(!matches!(union_layout, UnionLayout::NonRecursive(..)));
|
||||
union_layout
|
||||
}
|
||||
|
@ -342,8 +342,8 @@ fn build_neq<'a, 'ctx>(
|
|||
);
|
||||
}
|
||||
|
||||
match layout_interner.get(lhs_layout) {
|
||||
Layout::Builtin(builtin) => build_neq_builtin(
|
||||
match layout_interner.get(lhs_layout).repr {
|
||||
LayoutRepr::Builtin(builtin) => build_neq_builtin(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
|
@ -353,7 +353,7 @@ fn build_neq<'a, 'ctx>(
|
|||
&builtin,
|
||||
),
|
||||
|
||||
Layout::Struct { field_layouts, .. } => {
|
||||
LayoutRepr::Struct { field_layouts, .. } => {
|
||||
let is_equal = build_struct_eq(
|
||||
env,
|
||||
layout_interner,
|
||||
|
@ -370,7 +370,7 @@ fn build_neq<'a, 'ctx>(
|
|||
result.into()
|
||||
}
|
||||
|
||||
Layout::Union(union_layout) => {
|
||||
LayoutRepr::Union(union_layout) => {
|
||||
let is_equal = build_tag_eq(
|
||||
env,
|
||||
layout_interner,
|
||||
|
@ -387,7 +387,7 @@ fn build_neq<'a, 'ctx>(
|
|||
result.into()
|
||||
}
|
||||
|
||||
Layout::Boxed(inner_layout) => {
|
||||
LayoutRepr::Boxed(inner_layout) => {
|
||||
let is_equal = build_box_eq(
|
||||
env,
|
||||
layout_interner,
|
||||
|
@ -404,10 +404,10 @@ fn build_neq<'a, 'ctx>(
|
|||
result.into()
|
||||
}
|
||||
|
||||
Layout::RecursivePointer(_) => {
|
||||
LayoutRepr::RecursivePointer(_) => {
|
||||
unreachable!("recursion pointers should never be compared directly")
|
||||
}
|
||||
Layout::LambdaSet(_) => unreachable!("cannot compare closure"),
|
||||
LayoutRepr::LambdaSet(_) => unreachable!("cannot compare closure"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -424,12 +424,12 @@ fn build_list_eq<'a, 'ctx>(
|
|||
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||
|
||||
let symbol = Symbol::LIST_EQ;
|
||||
let element_layout = if let Layout::RecursivePointer(rec) = layout_interner.get(element_layout)
|
||||
{
|
||||
rec
|
||||
} else {
|
||||
element_layout
|
||||
};
|
||||
let element_layout =
|
||||
if let LayoutRepr::RecursivePointer(rec) = layout_interner.get(element_layout).repr {
|
||||
rec
|
||||
} else {
|
||||
element_layout
|
||||
};
|
||||
let fn_name = layout_ids
|
||||
.get(symbol, &element_layout)
|
||||
.to_symbol_string(symbol, &env.interns);
|
||||
|
@ -741,11 +741,11 @@ fn build_struct_eq_help<'a, 'ctx>(
|
|||
.build_extract_value(struct2, index as u32, "eq_field")
|
||||
.unwrap();
|
||||
|
||||
let are_equal = if let Layout::RecursivePointer(rec_layout) =
|
||||
layout_interner.get(*field_layout)
|
||||
let are_equal = if let LayoutRepr::RecursivePointer(rec_layout) =
|
||||
layout_interner.get(*field_layout).repr
|
||||
{
|
||||
debug_assert!(
|
||||
matches!(layout_interner.get(rec_layout), Layout::Union(union_layout) if !matches!(union_layout, UnionLayout::NonRecursive(..)))
|
||||
matches!(layout_interner.get(rec_layout).repr, LayoutRepr::Union(union_layout) if !matches!(union_layout, UnionLayout::NonRecursive(..)))
|
||||
);
|
||||
|
||||
let field_layout = rec_layout;
|
||||
|
|
|
@ -6,7 +6,8 @@ use inkwell::values::StructValue;
|
|||
use inkwell::AddressSpace;
|
||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||
use roc_mono::layout::{
|
||||
round_up_to_alignment, Builtin, InLayout, Layout, LayoutInterner, STLayoutInterner, UnionLayout,
|
||||
round_up_to_alignment, Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, STLayoutInterner,
|
||||
UnionLayout,
|
||||
};
|
||||
use roc_target::TargetInfo;
|
||||
|
||||
|
@ -33,9 +34,9 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>(
|
|||
layout_interner: &'env mut STLayoutInterner<'a>,
|
||||
layout: InLayout<'_>,
|
||||
) -> BasicTypeEnum<'ctx> {
|
||||
use Layout::*;
|
||||
use LayoutRepr::*;
|
||||
|
||||
match layout_interner.get(layout) {
|
||||
match layout_interner.get(layout).repr {
|
||||
Struct {
|
||||
field_layouts: sorted_fields,
|
||||
..
|
||||
|
@ -150,9 +151,9 @@ pub fn argument_type_from_layout<'a, 'ctx>(
|
|||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
layout: InLayout<'a>,
|
||||
) -> BasicTypeEnum<'ctx> {
|
||||
use Layout::*;
|
||||
use LayoutRepr::*;
|
||||
|
||||
match layout_interner.get(layout) {
|
||||
match layout_interner.get(layout).repr {
|
||||
LambdaSet(lambda_set) => {
|
||||
argument_type_from_layout(env, layout_interner, lambda_set.runtime_representation())
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use roc_error_macros::internal_error;
|
|||
use roc_module::symbol::Symbol;
|
||||
use roc_mono::ir::LookupType;
|
||||
use roc_mono::layout::{
|
||||
Builtin, InLayout, Layout, LayoutIds, LayoutInterner, STLayoutInterner, UnionLayout,
|
||||
Builtin, InLayout, Layout, LayoutIds, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout,
|
||||
};
|
||||
use roc_region::all::Region;
|
||||
|
||||
|
@ -296,8 +296,8 @@ fn build_clone<'a, 'ctx>(
|
|||
value: BasicValueEnum<'ctx>,
|
||||
layout: InLayout<'a>,
|
||||
) -> IntValue<'ctx> {
|
||||
match layout_interner.get(layout) {
|
||||
Layout::Builtin(builtin) => build_clone_builtin(
|
||||
match layout_interner.get(layout).repr {
|
||||
LayoutRepr::Builtin(builtin) => build_clone_builtin(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
|
@ -307,7 +307,7 @@ fn build_clone<'a, 'ctx>(
|
|||
builtin,
|
||||
),
|
||||
|
||||
Layout::Struct { field_layouts, .. } => build_clone_struct(
|
||||
LayoutRepr::Struct { field_layouts, .. } => build_clone_struct(
|
||||
env,
|
||||
layout_interner,
|
||||
layout_ids,
|
||||
|
@ -319,9 +319,9 @@ fn build_clone<'a, 'ctx>(
|
|||
|
||||
// Since we will never actually display functions (and hence lambda sets)
|
||||
// we just write nothing to the buffer
|
||||
Layout::LambdaSet(_) => cursors.extra_offset,
|
||||
LayoutRepr::LambdaSet(_) => cursors.extra_offset,
|
||||
|
||||
Layout::Union(union_layout) => {
|
||||
LayoutRepr::Union(union_layout) => {
|
||||
if layout_interner.safe_to_memcpy(layout) {
|
||||
let ptr = unsafe {
|
||||
env.builder.new_build_in_bounds_gep(
|
||||
|
@ -353,7 +353,7 @@ fn build_clone<'a, 'ctx>(
|
|||
}
|
||||
}
|
||||
|
||||
Layout::Boxed(inner_layout) => {
|
||||
LayoutRepr::Boxed(inner_layout) => {
|
||||
// write the offset
|
||||
build_copy(env, ptr, cursors.offset, cursors.extra_offset.into());
|
||||
|
||||
|
@ -384,7 +384,7 @@ fn build_clone<'a, 'ctx>(
|
|||
)
|
||||
}
|
||||
|
||||
Layout::RecursivePointer(rec_layout) => {
|
||||
LayoutRepr::RecursivePointer(rec_layout) => {
|
||||
let layout = rec_layout;
|
||||
|
||||
let bt = basic_type_from_layout(env, layout_interner, layout);
|
||||
|
@ -396,8 +396,8 @@ fn build_clone<'a, 'ctx>(
|
|||
"i64_to_opaque",
|
||||
);
|
||||
|
||||
let union_layout = match layout_interner.get(rec_layout) {
|
||||
Layout::Union(union_layout) => {
|
||||
let union_layout = match layout_interner.get(rec_layout).repr {
|
||||
LayoutRepr::Union(union_layout) => {
|
||||
debug_assert!(!matches!(union_layout, UnionLayout::NonRecursive(..)));
|
||||
union_layout
|
||||
}
|
||||
|
@ -476,7 +476,9 @@ fn build_clone_tag<'a, 'ctx>(
|
|||
value: BasicValueEnum<'ctx>,
|
||||
union_layout: UnionLayout<'a>,
|
||||
) -> IntValue<'ctx> {
|
||||
let layout = layout_interner.insert(Layout::Union(union_layout));
|
||||
let layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
let layout_id = layout_ids.get(Symbol::CLONE, &layout);
|
||||
let fn_name = layout_id.to_symbol_string(Symbol::CLONE, &env.interns);
|
||||
|
||||
|
|
|
@ -12,7 +12,10 @@ use roc_error_macros::internal_error;
|
|||
use roc_module::{low_level::LowLevel, symbol::Symbol};
|
||||
use roc_mono::{
|
||||
ir::HigherOrderLowLevel,
|
||||
layout::{Builtin, InLayout, LambdaSet, Layout, LayoutIds, LayoutInterner, STLayoutInterner},
|
||||
layout::{
|
||||
Builtin, InLayout, LambdaSet, Layout, LayoutIds, LayoutInterner, LayoutRepr,
|
||||
STLayoutInterner,
|
||||
},
|
||||
list_element_layout,
|
||||
};
|
||||
use roc_target::PtrWidth;
|
||||
|
@ -193,16 +196,18 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
// Str.toNum : Str -> Result (Num *) {}
|
||||
arguments!(string);
|
||||
|
||||
let number_layout = match layout_interner.get(layout) {
|
||||
Layout::Struct { field_layouts, .. } => field_layouts[0], // TODO: why is it sometimes a struct?
|
||||
let number_layout = match layout_interner.get(layout).repr {
|
||||
LayoutRepr::Struct { field_layouts, .. } => field_layouts[0], // TODO: why is it sometimes a struct?
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
// match on the return layout to figure out which zig builtin we need
|
||||
let intrinsic = match layout_interner.get(number_layout) {
|
||||
Layout::Builtin(Builtin::Int(int_width)) => &bitcode::STR_TO_INT[int_width],
|
||||
Layout::Builtin(Builtin::Float(float_width)) => &bitcode::STR_TO_FLOAT[float_width],
|
||||
Layout::Builtin(Builtin::Decimal) => bitcode::DEC_FROM_STR,
|
||||
let intrinsic = match layout_interner.get(number_layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => &bitcode::STR_TO_INT[int_width],
|
||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
||||
&bitcode::STR_TO_FLOAT[float_width]
|
||||
}
|
||||
LayoutRepr::Builtin(Builtin::Decimal) => bitcode::DEC_FROM_STR,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -220,9 +225,11 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
intrinsic,
|
||||
),
|
||||
None => {
|
||||
let return_type_name = match layout_interner.get(number_layout) {
|
||||
Layout::Builtin(Builtin::Int(int_width)) => int_width.type_name(),
|
||||
Layout::Builtin(Builtin::Decimal) => {
|
||||
let return_type_name = match layout_interner.get(number_layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
|
||||
int_width.type_name()
|
||||
}
|
||||
LayoutRepr::Builtin(Builtin::Decimal) => {
|
||||
// zig picks 128 for dec.RocDec
|
||||
"i128"
|
||||
}
|
||||
|
@ -268,12 +275,12 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
}
|
||||
}
|
||||
PtrWidth::Bytes8 => {
|
||||
let cc_return_by_pointer = match layout_interner.get(number_layout) {
|
||||
Layout::Builtin(Builtin::Int(int_width)) => {
|
||||
let cc_return_by_pointer = match layout_interner.get(number_layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
|
||||
(int_width.stack_size() as usize > env.target_info.ptr_size())
|
||||
.then_some(int_width.type_name())
|
||||
}
|
||||
Layout::Builtin(Builtin::Decimal) => {
|
||||
LayoutRepr::Builtin(Builtin::Decimal) => {
|
||||
// zig picks 128 for dec.RocDec
|
||||
Some("i128")
|
||||
}
|
||||
|
@ -314,8 +321,8 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
let (int, int_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
let int = int.into_int_value();
|
||||
|
||||
let int_width = match layout_interner.get(int_layout) {
|
||||
Layout::Builtin(Builtin::Int(int_width)) => int_width,
|
||||
let int_width = match layout_interner.get(int_layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -333,8 +340,8 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
|
||||
let (float, float_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
|
||||
let float_width = match layout_interner.get(float_layout) {
|
||||
Layout::Builtin(Builtin::Float(float_width)) => float_width,
|
||||
let float_width = match layout_interner.get(float_layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => float_width,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -843,8 +850,8 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
// Num.toStr : Num a -> Str
|
||||
arguments_with_layouts!((num, num_layout));
|
||||
|
||||
match layout_interner.get(num_layout) {
|
||||
Layout::Builtin(Builtin::Int(int_width)) => {
|
||||
match layout_interner.get(num_layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
|
||||
let int = num.into_int_value();
|
||||
|
||||
call_str_bitcode_fn(
|
||||
|
@ -855,11 +862,11 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
&bitcode::STR_FROM_INT[int_width],
|
||||
)
|
||||
}
|
||||
Layout::Builtin(Builtin::Float(_float_width)) => {
|
||||
LayoutRepr::Builtin(Builtin::Float(_float_width)) => {
|
||||
let (float, float_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
|
||||
let float_width = match layout_interner.get(float_layout) {
|
||||
Layout::Builtin(Builtin::Float(float_width)) => float_width,
|
||||
let float_width = match layout_interner.get(float_layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => float_width,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
|
@ -871,7 +878,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
&bitcode::STR_FROM_FLOAT[float_width],
|
||||
)
|
||||
}
|
||||
Layout::Builtin(Builtin::Decimal) => dec_to_str(env, num),
|
||||
LayoutRepr::Builtin(Builtin::Decimal) => dec_to_str(env, num),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -897,8 +904,8 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
| NumCountOneBits => {
|
||||
arguments_with_layouts!((arg, arg_layout));
|
||||
|
||||
match layout_interner.get(arg_layout) {
|
||||
Layout::Builtin(arg_builtin) => {
|
||||
match layout_interner.get(arg_layout).repr {
|
||||
LayoutRepr::Builtin(arg_builtin) => {
|
||||
use roc_mono::layout::Builtin::*;
|
||||
|
||||
match arg_builtin {
|
||||
|
@ -985,10 +992,10 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
|
||||
use inkwell::FloatPredicate;
|
||||
match (
|
||||
layout_interner.get(lhs_layout),
|
||||
layout_interner.get(rhs_layout),
|
||||
layout_interner.get(lhs_layout).repr,
|
||||
layout_interner.get(rhs_layout).repr,
|
||||
) {
|
||||
(Layout::Builtin(lhs_builtin), Layout::Builtin(rhs_builtin))
|
||||
(LayoutRepr::Builtin(lhs_builtin), LayoutRepr::Builtin(rhs_builtin))
|
||||
if lhs_builtin == rhs_builtin =>
|
||||
{
|
||||
use roc_mono::layout::Builtin::*;
|
||||
|
@ -1141,8 +1148,8 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
NumToFloatCast => {
|
||||
arguments_with_layouts!((arg, arg_layout));
|
||||
|
||||
match layout_interner.get(arg_layout) {
|
||||
Layout::Builtin(Builtin::Int(width)) => {
|
||||
match layout_interner.get(arg_layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||
// Converting from int to float
|
||||
let int_val = arg.into_int_value();
|
||||
let dest =
|
||||
|
@ -1158,7 +1165,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
.into()
|
||||
}
|
||||
}
|
||||
Layout::Builtin(Builtin::Float(_)) => {
|
||||
LayoutRepr::Builtin(Builtin::Float(_)) => {
|
||||
// Converting from float to float - e.g. F64 to F32, or vice versa
|
||||
let dest =
|
||||
basic_type_from_layout(env, layout_interner, layout).into_float_type();
|
||||
|
@ -1167,7 +1174,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
.build_float_cast(arg.into_float_value(), dest, "cast_float_to_float")
|
||||
.into()
|
||||
}
|
||||
Layout::Builtin(Builtin::Decimal) => {
|
||||
LayoutRepr::Builtin(Builtin::Decimal) => {
|
||||
todo!("Support converting Dec values to floats.");
|
||||
}
|
||||
other => {
|
||||
|
@ -1263,8 +1270,8 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
"cast_to_i8_ptr",
|
||||
);
|
||||
|
||||
let value_ptr = match layout_interner.get(data_layout) {
|
||||
Layout::Union(union_layout)
|
||||
let value_ptr = match layout_interner.get(data_layout).repr {
|
||||
LayoutRepr::Union(union_layout)
|
||||
if union_layout.stores_tag_id_in_pointer(env.target_info) =>
|
||||
{
|
||||
tag_pointer_clear_tag_id(env, ptr)
|
||||
|
@ -1529,10 +1536,10 @@ pub fn build_num_binop<'a, 'ctx>(
|
|||
op: LowLevel,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
match (
|
||||
layout_interner.get(lhs_layout),
|
||||
layout_interner.get(rhs_layout),
|
||||
layout_interner.get(lhs_layout).repr,
|
||||
layout_interner.get(rhs_layout).repr,
|
||||
) {
|
||||
(Layout::Builtin(lhs_builtin), Layout::Builtin(rhs_builtin))
|
||||
(LayoutRepr::Builtin(lhs_builtin), LayoutRepr::Builtin(rhs_builtin))
|
||||
if lhs_builtin == rhs_builtin =>
|
||||
{
|
||||
use roc_mono::layout::Builtin::*;
|
||||
|
@ -1975,8 +1982,8 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
|||
NumToFrac => {
|
||||
// This is an Int, so we need to convert it.
|
||||
|
||||
let target_float_type = match layout_interner.get(return_layout) {
|
||||
Layout::Builtin(Builtin::Float(float_width)) => {
|
||||
let target_float_type = match layout_interner.get(return_layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
||||
convert::float_type_from_float_width(env, float_width)
|
||||
}
|
||||
_ => internal_error!("There can only be floats here!"),
|
||||
|
@ -1992,8 +1999,8 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
|||
NumToIntChecked => {
|
||||
// return_layout : Result N [OutOfBounds]* ~ { result: N, out_of_bounds: bool }
|
||||
|
||||
let target_int_width = match layout_interner.get(return_layout) {
|
||||
Layout::Struct { field_layouts, .. } if field_layouts.len() == 2 => {
|
||||
let target_int_width = match layout_interner.get(return_layout).repr {
|
||||
LayoutRepr::Struct { field_layouts, .. } if field_layouts.len() == 2 => {
|
||||
debug_assert!(matches!(field_layouts[1], Layout::BOOL));
|
||||
field_layouts[0].to_int_width()
|
||||
}
|
||||
|
@ -2272,8 +2279,8 @@ fn build_float_unary_op<'a, 'ctx>(
|
|||
NumSqrtUnchecked => env.call_intrinsic(&LLVM_SQRT[float_width], &[arg.into()]),
|
||||
NumLogUnchecked => env.call_intrinsic(&LLVM_LOG[float_width], &[arg.into()]),
|
||||
NumToFrac => {
|
||||
let return_width = match layout_interner.get(layout) {
|
||||
Layout::Builtin(Builtin::Float(return_width)) => return_width,
|
||||
let return_width = match layout_interner.get(layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Float(return_width)) => return_width,
|
||||
_ => internal_error!("Layout for returning is not Float : {:?}", layout),
|
||||
};
|
||||
match (float_width, return_width) {
|
||||
|
@ -2294,8 +2301,8 @@ fn build_float_unary_op<'a, 'ctx>(
|
|||
}
|
||||
}
|
||||
NumCeiling => {
|
||||
let (return_signed, return_type) = match layout_interner.get(layout) {
|
||||
Layout::Builtin(Builtin::Int(int_width)) => (
|
||||
let (return_signed, return_type) = match layout_interner.get(layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => (
|
||||
int_width.is_signed(),
|
||||
convert::int_type_from_int_width(env, int_width),
|
||||
),
|
||||
|
@ -2314,8 +2321,8 @@ fn build_float_unary_op<'a, 'ctx>(
|
|||
)
|
||||
}
|
||||
NumFloor => {
|
||||
let (return_signed, return_type) = match layout_interner.get(layout) {
|
||||
Layout::Builtin(Builtin::Int(int_width)) => (
|
||||
let (return_signed, return_type) = match layout_interner.get(layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => (
|
||||
int_width.is_signed(),
|
||||
convert::int_type_from_int_width(env, int_width),
|
||||
),
|
||||
|
@ -2334,8 +2341,8 @@ fn build_float_unary_op<'a, 'ctx>(
|
|||
)
|
||||
}
|
||||
NumRound => {
|
||||
let (return_signed, return_type) = match layout_interner.get(layout) {
|
||||
Layout::Builtin(Builtin::Int(int_width)) => (
|
||||
let (return_signed, return_type) = match layout_interner.get(layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => (
|
||||
int_width.is_signed(),
|
||||
convert::int_type_from_int_width(env, int_width),
|
||||
),
|
||||
|
@ -2427,12 +2434,12 @@ pub(crate) fn run_higher_order_low_level<'a, 'ctx>(
|
|||
let (function, closure, closure_layout) = function_details!();
|
||||
|
||||
match (
|
||||
layout_interner.get(list_layout),
|
||||
layout_interner.get(return_layout),
|
||||
layout_interner.get(list_layout).repr,
|
||||
layout_interner.get(return_layout).repr,
|
||||
) {
|
||||
(
|
||||
Layout::Builtin(Builtin::List(element_layout)),
|
||||
Layout::Builtin(Builtin::List(result_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(element_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(result_layout)),
|
||||
) => {
|
||||
let argument_layouts = &[element_layout];
|
||||
|
||||
|
@ -2467,14 +2474,14 @@ pub(crate) fn run_higher_order_low_level<'a, 'ctx>(
|
|||
let (function, closure, closure_layout) = function_details!();
|
||||
|
||||
match (
|
||||
layout_interner.get(list1_layout),
|
||||
layout_interner.get(list2_layout),
|
||||
layout_interner.get(return_layout),
|
||||
layout_interner.get(list1_layout).repr,
|
||||
layout_interner.get(list2_layout).repr,
|
||||
layout_interner.get(return_layout).repr,
|
||||
) {
|
||||
(
|
||||
Layout::Builtin(Builtin::List(element1_layout)),
|
||||
Layout::Builtin(Builtin::List(element2_layout)),
|
||||
Layout::Builtin(Builtin::List(result_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(element1_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(element2_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(result_layout)),
|
||||
) => {
|
||||
let argument_layouts = &[element1_layout, element2_layout];
|
||||
|
||||
|
@ -2513,16 +2520,16 @@ pub(crate) fn run_higher_order_low_level<'a, 'ctx>(
|
|||
let (function, closure, closure_layout) = function_details!();
|
||||
|
||||
match (
|
||||
layout_interner.get(list1_layout),
|
||||
layout_interner.get(list2_layout),
|
||||
layout_interner.get(list3_layout),
|
||||
layout_interner.get(return_layout),
|
||||
layout_interner.get(list1_layout).repr,
|
||||
layout_interner.get(list2_layout).repr,
|
||||
layout_interner.get(list3_layout).repr,
|
||||
layout_interner.get(return_layout).repr,
|
||||
) {
|
||||
(
|
||||
Layout::Builtin(Builtin::List(element1_layout)),
|
||||
Layout::Builtin(Builtin::List(element2_layout)),
|
||||
Layout::Builtin(Builtin::List(element3_layout)),
|
||||
Layout::Builtin(Builtin::List(result_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(element1_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(element2_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(element3_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(result_layout)),
|
||||
) => {
|
||||
let argument_layouts = &[element1_layout, element2_layout, element3_layout];
|
||||
|
||||
|
@ -2564,18 +2571,18 @@ pub(crate) fn run_higher_order_low_level<'a, 'ctx>(
|
|||
let (function, closure, closure_layout) = function_details!();
|
||||
|
||||
match (
|
||||
layout_interner.get(list1_layout),
|
||||
layout_interner.get(list2_layout),
|
||||
layout_interner.get(list3_layout),
|
||||
layout_interner.get(list4_layout),
|
||||
layout_interner.get(return_layout),
|
||||
layout_interner.get(list1_layout).repr,
|
||||
layout_interner.get(list2_layout).repr,
|
||||
layout_interner.get(list3_layout).repr,
|
||||
layout_interner.get(list4_layout).repr,
|
||||
layout_interner.get(return_layout).repr,
|
||||
) {
|
||||
(
|
||||
Layout::Builtin(Builtin::List(element1_layout)),
|
||||
Layout::Builtin(Builtin::List(element2_layout)),
|
||||
Layout::Builtin(Builtin::List(element3_layout)),
|
||||
Layout::Builtin(Builtin::List(element4_layout)),
|
||||
Layout::Builtin(Builtin::List(result_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(element1_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(element2_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(element3_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(element4_layout)),
|
||||
LayoutRepr::Builtin(Builtin::List(result_layout)),
|
||||
) => {
|
||||
let argument_layouts = &[
|
||||
element1_layout,
|
||||
|
@ -2621,8 +2628,8 @@ pub(crate) fn run_higher_order_low_level<'a, 'ctx>(
|
|||
|
||||
let (function, closure, closure_layout) = function_details!();
|
||||
|
||||
match layout_interner.get(list_layout) {
|
||||
Layout::Builtin(Builtin::List(element_layout)) => {
|
||||
match layout_interner.get(list_layout).repr {
|
||||
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
|
||||
use crate::llvm::bitcode::build_compare_wrapper;
|
||||
|
||||
let argument_layouts = &[element_layout, element_layout];
|
||||
|
@ -2670,8 +2677,11 @@ fn load_symbol_and_lambda_set<'a, 'ctx>(
|
|||
scope: &Scope<'a, 'ctx>,
|
||||
symbol: &Symbol,
|
||||
) -> (BasicValueEnum<'ctx>, LambdaSet<'a>) {
|
||||
match scope.get(symbol).map(|(l, v)| (layout_interner.get(*l), v)) {
|
||||
Some((Layout::LambdaSet(lambda_set), ptr)) => (*ptr, lambda_set),
|
||||
match scope
|
||||
.get(symbol)
|
||||
.map(|(l, v)| (layout_interner.get(*l).repr, v))
|
||||
{
|
||||
Some((LayoutRepr::LambdaSet(lambda_set), ptr)) => (*ptr, lambda_set),
|
||||
Some((other, ptr)) => panic!("Not a lambda set: {:?}, {:?}", other, ptr),
|
||||
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ use inkwell::{AddressSpace, IntPredicate};
|
|||
use roc_module::symbol::Interns;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_mono::layout::{
|
||||
Builtin, InLayout, Layout, LayoutIds, LayoutInterner, STLayoutInterner, UnionLayout,
|
||||
Builtin, InLayout, Layout, LayoutIds, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout,
|
||||
};
|
||||
|
||||
use super::build::{cast_if_necessary_for_opaque_recursive_pointers, load_roc_value, FunctionSpec};
|
||||
|
@ -470,8 +470,8 @@ fn modify_refcount_layout_help<'a, 'ctx>(
|
|||
None => return,
|
||||
};
|
||||
|
||||
match layout_interner.get(layout) {
|
||||
Layout::RecursivePointer(rec_layout) => {
|
||||
match layout_interner.get(layout).repr {
|
||||
LayoutRepr::RecursivePointer(rec_layout) => {
|
||||
let layout = rec_layout;
|
||||
|
||||
let bt = basic_type_from_layout(env, layout_interner, layout);
|
||||
|
@ -525,9 +525,9 @@ fn modify_refcount_layout_build_function<'a, 'ctx>(
|
|||
mode: Mode,
|
||||
layout: InLayout<'a>,
|
||||
) -> Option<FunctionValue<'ctx>> {
|
||||
use Layout::*;
|
||||
use LayoutRepr::*;
|
||||
|
||||
match layout_interner.get(layout) {
|
||||
match layout_interner.get(layout).repr {
|
||||
Builtin(builtin) => {
|
||||
modify_refcount_builtin(env, layout_interner, layout_ids, mode, layout, &builtin)
|
||||
}
|
||||
|
@ -569,7 +569,7 @@ fn modify_refcount_layout_build_function<'a, 'ctx>(
|
|||
Some(function)
|
||||
}
|
||||
|
||||
Layout::RecursivePointer(rec_layout) => {
|
||||
LayoutRepr::RecursivePointer(rec_layout) => {
|
||||
let layout = rec_layout;
|
||||
|
||||
let function = modify_refcount_layout_build_function(
|
||||
|
@ -602,14 +602,16 @@ fn modify_refcount_list<'a, 'ctx>(
|
|||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||
|
||||
let element_layout = if let Layout::RecursivePointer(rec) = layout_interner.get(element_layout)
|
||||
{
|
||||
rec
|
||||
} else {
|
||||
element_layout
|
||||
};
|
||||
let element_layout =
|
||||
if let LayoutRepr::RecursivePointer(rec) = layout_interner.get(element_layout).repr {
|
||||
rec
|
||||
} else {
|
||||
element_layout
|
||||
};
|
||||
|
||||
let list_layout = layout_interner.insert(Layout::Builtin(Builtin::List(element_layout)));
|
||||
let list_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::List(element_layout)),
|
||||
});
|
||||
let (_, fn_name) = function_name_from_mode(
|
||||
layout_ids,
|
||||
&env.interns,
|
||||
|
@ -803,15 +805,18 @@ fn modify_refcount_str_help<'a, 'ctx>(
|
|||
let parent = fn_val;
|
||||
|
||||
let str_type = zig_str_type(env);
|
||||
let str_wrapper =
|
||||
if Layout::Builtin(Builtin::Str).is_passed_by_reference(layout_interner, env.target_info) {
|
||||
env.builder
|
||||
.new_build_load(str_type, arg_val.into_pointer_value(), "load_str_to_stack")
|
||||
} else {
|
||||
// it's already a struct, just do nothing
|
||||
debug_assert!(arg_val.is_struct_value());
|
||||
arg_val
|
||||
};
|
||||
let str_wrapper = if (Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::Str),
|
||||
})
|
||||
.is_passed_by_reference(layout_interner, env.target_info)
|
||||
{
|
||||
env.builder
|
||||
.new_build_load(str_type, arg_val.into_pointer_value(), "load_str_to_stack")
|
||||
} else {
|
||||
// it's already a struct, just do nothing
|
||||
debug_assert!(arg_val.is_struct_value());
|
||||
arg_val
|
||||
};
|
||||
let str_wrapper = str_wrapper.into_struct_value();
|
||||
|
||||
let capacity = builder
|
||||
|
@ -857,7 +862,9 @@ fn modify_refcount_boxed<'a, 'ctx>(
|
|||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||
|
||||
let boxed_layout = layout_interner.insert(Layout::Boxed(inner_layout));
|
||||
let boxed_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(inner_layout),
|
||||
});
|
||||
|
||||
let (_, fn_name) = function_name_from_mode(
|
||||
layout_ids,
|
||||
|
@ -919,7 +926,9 @@ fn modify_refcount_box_help<'a, 'ctx>(
|
|||
let boxed = arg_val.into_pointer_value();
|
||||
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, boxed);
|
||||
let call_mode = mode_to_call_mode(fn_val, mode);
|
||||
let boxed_layout = layout_interner.insert(Layout::Boxed(inner_layout));
|
||||
let boxed_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(inner_layout),
|
||||
});
|
||||
|
||||
match mode {
|
||||
Mode::Inc => {
|
||||
|
@ -1063,7 +1072,9 @@ fn build_rec_union<'a, 'ctx>(
|
|||
mode: Mode,
|
||||
union_layout: UnionLayout<'a>,
|
||||
) -> FunctionValue<'ctx> {
|
||||
let layout = layout_interner.insert(Layout::Union(union_layout));
|
||||
let layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
|
||||
let (_, fn_name) = function_name_from_mode(
|
||||
layout_ids,
|
||||
|
@ -1166,7 +1177,9 @@ fn build_rec_union_help<'a, 'ctx>(
|
|||
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, value_ptr);
|
||||
let call_mode = mode_to_call_mode(fn_val, mode);
|
||||
|
||||
let layout = layout_interner.insert(Layout::Union(union_layout));
|
||||
let layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
|
||||
match mode {
|
||||
Mode::Inc => {
|
||||
|
@ -1288,7 +1301,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
|||
let mut deferred_nonrec = Vec::new_in(env.arena);
|
||||
|
||||
for (i, field_layout) in field_layouts.iter().enumerate() {
|
||||
if let Layout::RecursivePointer(_) = layout_interner.get(*field_layout) {
|
||||
if let LayoutRepr::RecursivePointer(_) = layout_interner.get(*field_layout).repr {
|
||||
// this field has type `*i64`, but is really a pointer to the data we want
|
||||
let elem_pointer = env
|
||||
.builder
|
||||
|
@ -1309,7 +1322,9 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
|||
debug_assert!(ptr_as_i64_ptr.is_pointer_value());
|
||||
|
||||
// therefore we must cast it to our desired type
|
||||
let union_layout = layout_interner.insert(Layout::Union(union_layout));
|
||||
let union_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
let union_type = basic_type_from_layout(env, layout_interner, union_layout);
|
||||
let recursive_field_ptr = cast_basic_basic(env.builder, ptr_as_i64_ptr, union_type);
|
||||
|
||||
|
@ -1347,7 +1362,9 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
|||
match decrement_or_reuse {
|
||||
DecOrReuse::Reuse => {}
|
||||
DecOrReuse::Dec => {
|
||||
let union_layout = layout_interner.insert(Layout::Union(union_layout));
|
||||
let union_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
refcount_ptr.modify(call_mode, union_layout, env, layout_interner);
|
||||
}
|
||||
}
|
||||
|
@ -1405,7 +1422,9 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
|||
|
||||
// increment/decrement the cons-cell itself
|
||||
if let DecOrReuse::Dec = decrement_or_reuse {
|
||||
let union_layout = layout_interner.insert(Layout::Union(union_layout));
|
||||
let union_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
refcount_ptr.modify(call_mode, union_layout, env, layout_interner);
|
||||
}
|
||||
}
|
||||
|
@ -1465,7 +1484,9 @@ pub fn build_reset<'a, 'ctx>(
|
|||
) -> FunctionValue<'ctx> {
|
||||
let mode = Mode::Dec;
|
||||
|
||||
let union_layout_in = layout_interner.insert(Layout::Union(union_layout));
|
||||
let union_layout_in = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
let layout_id = layout_ids.get(Symbol::DEC, &union_layout_in);
|
||||
let fn_name = layout_id.to_symbol_string(Symbol::DEC, &env.interns);
|
||||
let fn_name = format!("{}_reset", fn_name);
|
||||
|
@ -1561,7 +1582,9 @@ fn build_reuse_rec_union_help<'a, 'ctx>(
|
|||
|
||||
env.builder.position_at_end(should_recurse_block);
|
||||
|
||||
let layout = layout_interner.insert(Layout::Union(union_layout));
|
||||
let layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
|
||||
let do_recurse_block = env.context.append_basic_block(parent, "do_recurse");
|
||||
let no_recurse_block = env.context.append_basic_block(parent, "no_recurse");
|
||||
|
@ -1623,7 +1646,9 @@ fn modify_refcount_nonrecursive<'a, 'ctx>(
|
|||
fields: &'a [&'a [InLayout<'a>]],
|
||||
) -> FunctionValue<'ctx> {
|
||||
let union_layout = UnionLayout::NonRecursive(fields);
|
||||
let layout = layout_interner.insert(Layout::Union(union_layout));
|
||||
let layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
|
||||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||
|
@ -1693,7 +1718,9 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
|
|||
let before_block = env.builder.get_insert_block().expect("to be in a function");
|
||||
|
||||
let union_layout = UnionLayout::NonRecursive(tags);
|
||||
let layout = layout_interner.insert(Layout::Union(union_layout));
|
||||
let layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
let union_struct_type = basic_type_from_layout(env, layout_interner, layout).into_struct_type();
|
||||
|
||||
// read the tag_id
|
||||
|
@ -1761,7 +1788,9 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
|
|||
);
|
||||
|
||||
for (i, field_layout) in field_layouts.iter().enumerate() {
|
||||
if let Layout::RecursivePointer(union_layout) = layout_interner.get(*field_layout) {
|
||||
if let LayoutRepr::RecursivePointer(union_layout) =
|
||||
layout_interner.get(*field_layout).repr
|
||||
{
|
||||
// This field is a pointer to the recursive pointer.
|
||||
let field_ptr = env
|
||||
.builder
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue