mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
merge remote/main, fix merge conflicts, update mono
This commit is contained in:
commit
15b7b62c4f
45 changed files with 850 additions and 638 deletions
|
@ -403,7 +403,7 @@ fn build_entry_point<'a>(
|
||||||
|
|
||||||
let block = builder.add_block();
|
let block = builder.add_block();
|
||||||
|
|
||||||
let struct_layout = interner.insert_no_semantic(LayoutRepr::struct_(layouts));
|
let struct_layout = interner.insert_direct_no_semantic(LayoutRepr::struct_(layouts));
|
||||||
let type_id = layout_spec(env, &mut builder, interner, struct_layout)?;
|
let type_id = layout_spec(env, &mut builder, interner, struct_layout)?;
|
||||||
|
|
||||||
let argument = builder.add_unknown_with(block, &[], type_id)?;
|
let argument = builder.add_unknown_with(block, &[], type_id)?;
|
||||||
|
@ -461,7 +461,7 @@ fn proc_spec<'a>(
|
||||||
|
|
||||||
let root = BlockExpr(block, value_id);
|
let root = BlockExpr(block, value_id);
|
||||||
let args_struct_layout =
|
let args_struct_layout =
|
||||||
interner.insert_no_semantic(LayoutRepr::struct_(argument_layouts.into_bump_slice()));
|
interner.insert_direct_no_semantic(LayoutRepr::struct_(argument_layouts.into_bump_slice()));
|
||||||
let arg_type_id = layout_spec(&mut env, &mut builder, interner, args_struct_layout)?;
|
let arg_type_id = layout_spec(&mut env, &mut builder, interner, args_struct_layout)?;
|
||||||
let ret_type_id = layout_spec(&mut env, &mut builder, interner, proc.ret_layout)?;
|
let ret_type_id = layout_spec(&mut env, &mut builder, interner, proc.ret_layout)?;
|
||||||
|
|
||||||
|
@ -851,8 +851,9 @@ fn call_spec<'a>(
|
||||||
|
|
||||||
let output_element_type = layout_spec(env, builder, interner, *return_layout)?;
|
let output_element_type = layout_spec(env, builder, interner, *return_layout)?;
|
||||||
|
|
||||||
let state_layout = interner
|
let state_layout = interner.insert_direct_no_semantic(LayoutRepr::Builtin(
|
||||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(*return_layout)));
|
Builtin::List(*return_layout),
|
||||||
|
));
|
||||||
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
||||||
|
|
||||||
let init_state = new_list(builder, block, output_element_type)?;
|
let init_state = new_list(builder, block, output_element_type)?;
|
||||||
|
@ -880,7 +881,7 @@ fn call_spec<'a>(
|
||||||
let arg0_layout = argument_layouts[0];
|
let arg0_layout = argument_layouts[0];
|
||||||
|
|
||||||
let state_layout = interner
|
let state_layout = interner
|
||||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(arg0_layout)));
|
.insert_direct_no_semantic(LayoutRepr::Builtin(Builtin::List(arg0_layout)));
|
||||||
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
||||||
let init_state = list;
|
let init_state = list;
|
||||||
|
|
||||||
|
@ -907,8 +908,9 @@ fn call_spec<'a>(
|
||||||
|
|
||||||
let output_element_type = layout_spec(env, builder, interner, *return_layout)?;
|
let output_element_type = layout_spec(env, builder, interner, *return_layout)?;
|
||||||
|
|
||||||
let state_layout = interner
|
let state_layout = interner.insert_direct_no_semantic(LayoutRepr::Builtin(
|
||||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(*return_layout)));
|
Builtin::List(*return_layout),
|
||||||
|
));
|
||||||
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
||||||
|
|
||||||
let init_state = new_list(builder, block, output_element_type)?;
|
let init_state = new_list(builder, block, output_element_type)?;
|
||||||
|
@ -941,8 +943,9 @@ fn call_spec<'a>(
|
||||||
|
|
||||||
let output_element_type = layout_spec(env, builder, interner, *return_layout)?;
|
let output_element_type = layout_spec(env, builder, interner, *return_layout)?;
|
||||||
|
|
||||||
let state_layout = interner
|
let state_layout = interner.insert_direct_no_semantic(LayoutRepr::Builtin(
|
||||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(*return_layout)));
|
Builtin::List(*return_layout),
|
||||||
|
));
|
||||||
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
||||||
|
|
||||||
let init_state = new_list(builder, block, output_element_type)?;
|
let init_state = new_list(builder, block, output_element_type)?;
|
||||||
|
@ -981,8 +984,9 @@ fn call_spec<'a>(
|
||||||
|
|
||||||
let output_element_type = layout_spec(env, builder, interner, *return_layout)?;
|
let output_element_type = layout_spec(env, builder, interner, *return_layout)?;
|
||||||
|
|
||||||
let state_layout = interner
|
let state_layout = interner.insert_direct_no_semantic(LayoutRepr::Builtin(
|
||||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(*return_layout)));
|
Builtin::List(*return_layout),
|
||||||
|
));
|
||||||
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
||||||
|
|
||||||
let init_state = new_list(builder, block, output_element_type)?;
|
let init_state = new_list(builder, block, output_element_type)?;
|
||||||
|
@ -1111,12 +1115,12 @@ fn lowlevel_spec<'a>(
|
||||||
let new_list = with_new_heap_cell(builder, block, bag)?;
|
let new_list = with_new_heap_cell(builder, block, bag)?;
|
||||||
|
|
||||||
// depending on the types, the list or value will come first in the struct
|
// depending on the types, the list or value will come first in the struct
|
||||||
let fields = match interner.get(layout).repr {
|
let fields = match interner.get_repr(layout) {
|
||||||
LayoutRepr::Struct(field_layouts) => field_layouts,
|
LayoutRepr::Struct(field_layouts) => field_layouts,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
match (interner.get(fields[0]).repr, interner.get(fields[1]).repr) {
|
match (interner.get_repr(fields[0]), interner.get_repr(fields[1])) {
|
||||||
(LayoutRepr::Builtin(Builtin::List(_)), LayoutRepr::Builtin(Builtin::List(_))) => {
|
(LayoutRepr::Builtin(Builtin::List(_)), LayoutRepr::Builtin(Builtin::List(_))) => {
|
||||||
// field name is the tie breaker, list is first in
|
// field name is the tie breaker, list is first in
|
||||||
// { list : List a, value : a }
|
// { list : List a, value : a }
|
||||||
|
@ -1144,7 +1148,7 @@ fn lowlevel_spec<'a>(
|
||||||
ListWithCapacity => {
|
ListWithCapacity => {
|
||||||
// essentially an empty list, capacity is not relevant for morphic
|
// essentially an empty list, capacity is not relevant for morphic
|
||||||
|
|
||||||
match interner.get(layout).repr {
|
match interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
|
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
|
||||||
let type_id = layout_spec(env, builder, interner, element_layout)?;
|
let type_id = layout_spec(env, builder, interner, element_layout)?;
|
||||||
new_list(builder, block, type_id)
|
new_list(builder, block, type_id)
|
||||||
|
@ -1440,7 +1444,7 @@ fn expr_spec<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EmptyArray => match interner.get(layout).repr {
|
EmptyArray => match interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
|
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
|
||||||
let type_id = layout_spec(env, builder, interner, element_layout)?;
|
let type_id = layout_spec(env, builder, interner, element_layout)?;
|
||||||
new_list(builder, block, type_id)
|
new_list(builder, block, type_id)
|
||||||
|
@ -1457,7 +1461,7 @@ fn expr_spec<'a>(
|
||||||
} => {
|
} => {
|
||||||
let tag_value_id = env.symbols[symbol];
|
let tag_value_id = env.symbols[symbol];
|
||||||
|
|
||||||
let union_layout = match interner.get(layout).repr {
|
let union_layout = match interner.get_repr(layout) {
|
||||||
LayoutRepr::Union(ul) => ul,
|
LayoutRepr::Union(ul) => ul,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
@ -1539,7 +1543,7 @@ fn layout_spec_help<'a>(
|
||||||
) -> Result<TypeId> {
|
) -> Result<TypeId> {
|
||||||
use LayoutRepr::*;
|
use LayoutRepr::*;
|
||||||
|
|
||||||
match interner.get(layout).repr {
|
match interner.get_repr(layout) {
|
||||||
Builtin(builtin) => builtin_spec(env, builder, interner, &builtin),
|
Builtin(builtin) => builtin_spec(env, builder, interner, &builtin),
|
||||||
Struct(field_layouts) => build_recursive_tuple_type(env, builder, interner, field_layouts),
|
Struct(field_layouts) => build_recursive_tuple_type(env, builder, interner, field_layouts),
|
||||||
LambdaSet(lambda_set) => {
|
LambdaSet(lambda_set) => {
|
||||||
|
@ -1578,7 +1582,7 @@ fn layout_spec_help<'a>(
|
||||||
builder.add_tuple_type(&[cell_type, inner_type])
|
builder.add_tuple_type(&[cell_type, inner_type])
|
||||||
}
|
}
|
||||||
// TODO(recursive-layouts): update once we have recursive pointer loops
|
// TODO(recursive-layouts): update once we have recursive pointer loops
|
||||||
RecursivePointer(union_layout) => match interner.get(union_layout).repr {
|
RecursivePointer(union_layout) => match interner.get_repr(union_layout) {
|
||||||
LayoutRepr::Union(union_layout) => {
|
LayoutRepr::Union(union_layout) => {
|
||||||
assert!(!matches!(union_layout, UnionLayout::NonRecursive(..)));
|
assert!(!matches!(union_layout, UnionLayout::NonRecursive(..)));
|
||||||
let type_name_bytes = recursive_tag_union_name_bytes(&union_layout).as_bytes();
|
let type_name_bytes = recursive_tag_union_name_bytes(&union_layout).as_bytes();
|
||||||
|
|
|
@ -888,7 +888,7 @@ impl<
|
||||||
|
|
||||||
fn move_return_value(&mut self, dst: &Symbol, ret_layout: &InLayout<'a>) {
|
fn move_return_value(&mut self, dst: &Symbol, ret_layout: &InLayout<'a>) {
|
||||||
// move return value to dst.
|
// move return value to dst.
|
||||||
let ret_repr = self.interner().get(*ret_layout).repr;
|
let ret_repr = self.interner().get_repr(*ret_layout);
|
||||||
match ret_repr {
|
match ret_repr {
|
||||||
single_register_integers!() => {
|
single_register_integers!() => {
|
||||||
let width = RegisterWidth::try_from_layout(ret_repr).unwrap();
|
let width = RegisterWidth::try_from_layout(ret_repr).unwrap();
|
||||||
|
@ -1070,7 +1070,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_num_abs(&mut self, dst: &Symbol, src: &Symbol, layout: &InLayout<'a>) {
|
fn build_num_abs(&mut self, dst: &Symbol, src: &Symbol, layout: &InLayout<'a>) {
|
||||||
match self.interner().get(*layout).repr {
|
match self.interner().get_repr(*layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
|
LayoutRepr::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
|
||||||
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||||
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
|
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
|
||||||
|
@ -1086,7 +1086,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_num_add(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
|
fn build_num_add(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
|
||||||
match self.layout_interner.get(*layout).repr {
|
match self.layout_interner.get_repr(*layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(quadword_and_smaller!())) => {
|
LayoutRepr::Builtin(Builtin::Int(quadword_and_smaller!())) => {
|
||||||
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||||
let src1_reg = self
|
let src1_reg = self
|
||||||
|
@ -1120,7 +1120,7 @@ impl<
|
||||||
src2: Symbol,
|
src2: Symbol,
|
||||||
layout: InLayout<'a>,
|
layout: InLayout<'a>,
|
||||||
) {
|
) {
|
||||||
match self.layout_interner.get(layout).repr {
|
match self.layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width @ quadword_and_smaller!())) => {
|
LayoutRepr::Builtin(Builtin::Int(width @ quadword_and_smaller!())) => {
|
||||||
let intrinsic = bitcode::NUM_ADD_SATURATED_INT[width].to_string();
|
let intrinsic = bitcode::NUM_ADD_SATURATED_INT[width].to_string();
|
||||||
self.build_fn_call(&dst, intrinsic, &[src1, src2], &[layout, layout], &layout);
|
self.build_fn_call(&dst, intrinsic, &[src1, src2], &[layout, layout], &layout);
|
||||||
|
@ -1161,7 +1161,7 @@ impl<
|
||||||
|
|
||||||
let base_offset = self.storage_manager.claim_stack_area(dst, struct_size);
|
let base_offset = self.storage_manager.claim_stack_area(dst, struct_size);
|
||||||
|
|
||||||
match self.layout_interner.get(*num_layout).repr {
|
match self.layout_interner.get_repr(*num_layout) {
|
||||||
LayoutRepr::Builtin(Int(
|
LayoutRepr::Builtin(Int(
|
||||||
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
|
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
|
||||||
)) => {
|
)) => {
|
||||||
|
@ -1208,7 +1208,7 @@ impl<
|
||||||
num_layout: &InLayout<'a>,
|
num_layout: &InLayout<'a>,
|
||||||
return_layout: &InLayout<'a>,
|
return_layout: &InLayout<'a>,
|
||||||
) {
|
) {
|
||||||
let function_name = match self.interner().get(*num_layout).repr {
|
let function_name = match self.interner().get_repr(*num_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => &bitcode::NUM_SUB_CHECKED_INT[width],
|
LayoutRepr::Builtin(Builtin::Int(width)) => &bitcode::NUM_SUB_CHECKED_INT[width],
|
||||||
LayoutRepr::Builtin(Builtin::Float(width)) => &bitcode::NUM_SUB_CHECKED_FLOAT[width],
|
LayoutRepr::Builtin(Builtin::Float(width)) => &bitcode::NUM_SUB_CHECKED_FLOAT[width],
|
||||||
LayoutRepr::Builtin(Builtin::Decimal) => bitcode::DEC_SUB_WITH_OVERFLOW,
|
LayoutRepr::Builtin(Builtin::Decimal) => bitcode::DEC_SUB_WITH_OVERFLOW,
|
||||||
|
@ -1227,7 +1227,7 @@ impl<
|
||||||
fn build_num_mul(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
|
fn build_num_mul(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
|
||||||
use Builtin::Int;
|
use Builtin::Int;
|
||||||
|
|
||||||
match self.layout_interner.get(*layout).repr {
|
match self.layout_interner.get_repr(*layout) {
|
||||||
LayoutRepr::Builtin(Int(
|
LayoutRepr::Builtin(Int(
|
||||||
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
|
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
|
||||||
)) => {
|
)) => {
|
||||||
|
@ -1291,7 +1291,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_num_div(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
|
fn build_num_div(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
|
||||||
match self.layout_interner.get(*layout).repr {
|
match self.layout_interner.get_repr(*layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(
|
LayoutRepr::Builtin(Builtin::Int(
|
||||||
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
|
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
|
||||||
)) => {
|
)) => {
|
||||||
|
@ -1347,7 +1347,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_num_rem(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
|
fn build_num_rem(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
|
||||||
match self.layout_interner.get(*layout).repr {
|
match self.layout_interner.get_repr(*layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(
|
LayoutRepr::Builtin(Builtin::Int(
|
||||||
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
|
IntWidth::I64 | IntWidth::I32 | IntWidth::I16 | IntWidth::I8,
|
||||||
)) => {
|
)) => {
|
||||||
|
@ -1391,7 +1391,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_num_neg(&mut self, dst: &Symbol, src: &Symbol, layout: &InLayout<'a>) {
|
fn build_num_neg(&mut self, dst: &Symbol, src: &Symbol, layout: &InLayout<'a>) {
|
||||||
match self.layout_interner.get(*layout).repr {
|
match self.layout_interner.get_repr(*layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
|
LayoutRepr::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
|
||||||
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||||
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
|
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
|
||||||
|
@ -1414,7 +1414,7 @@ impl<
|
||||||
src2: &Symbol,
|
src2: &Symbol,
|
||||||
layout: &InLayout<'a>,
|
layout: &InLayout<'a>,
|
||||||
) {
|
) {
|
||||||
match self.layout_interner.get(*layout).repr {
|
match self.layout_interner.get_repr(*layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(quadword_and_smaller!())) => {
|
LayoutRepr::Builtin(Builtin::Int(quadword_and_smaller!())) => {
|
||||||
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||||
let src1_reg = self
|
let src1_reg = self
|
||||||
|
@ -1430,7 +1430,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_eq(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, arg_layout: &InLayout<'a>) {
|
fn build_eq(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, arg_layout: &InLayout<'a>) {
|
||||||
let repr = self.interner().get(*arg_layout).repr;
|
let repr = self.interner().get_repr(*arg_layout);
|
||||||
match repr {
|
match repr {
|
||||||
single_register_int_builtins!() | LayoutRepr::BOOL => {
|
single_register_int_builtins!() | LayoutRepr::BOOL => {
|
||||||
let width = match repr {
|
let width = match repr {
|
||||||
|
@ -1546,7 +1546,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_neq(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, arg_layout: &InLayout<'a>) {
|
fn build_neq(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, arg_layout: &InLayout<'a>) {
|
||||||
match self.interner().get(*arg_layout).repr {
|
match self.interner().get_repr(*arg_layout) {
|
||||||
single_register_int_builtins!() | LayoutRepr::BOOL => {
|
single_register_int_builtins!() | LayoutRepr::BOOL => {
|
||||||
let width = match *arg_layout {
|
let width = match *arg_layout {
|
||||||
Layout::BOOL | Layout::I8 | Layout::U8 => RegisterWidth::W8,
|
Layout::BOOL | Layout::I8 | Layout::U8 => RegisterWidth::W8,
|
||||||
|
@ -1588,7 +1588,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_not(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>) {
|
fn build_not(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>) {
|
||||||
match self.interner().get(*arg_layout).repr {
|
match self.interner().get_repr(*arg_layout) {
|
||||||
LayoutRepr::BOOL => {
|
LayoutRepr::BOOL => {
|
||||||
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||||
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
|
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
|
||||||
|
@ -1613,8 +1613,8 @@ impl<
|
||||||
) {
|
) {
|
||||||
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
|
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
|
||||||
match (
|
match (
|
||||||
self.layout_interner.get(*arg_layout).repr,
|
self.layout_interner.get_repr(*arg_layout),
|
||||||
self.layout_interner.get(*ret_layout).repr,
|
self.layout_interner.get_repr(*ret_layout),
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
LayoutRepr::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::I64)),
|
LayoutRepr::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::I64)),
|
||||||
|
@ -1850,8 +1850,9 @@ impl<
|
||||||
let new_element_layout = higher_order.passed_function.return_layout;
|
let new_element_layout = higher_order.passed_function.return_layout;
|
||||||
|
|
||||||
let input_list_layout = LayoutRepr::Builtin(Builtin::List(old_element_layout));
|
let input_list_layout = LayoutRepr::Builtin(Builtin::List(old_element_layout));
|
||||||
let input_list_in_layout =
|
let input_list_in_layout = self
|
||||||
self.layout_interner.insert_no_semantic(input_list_layout);
|
.layout_interner
|
||||||
|
.insert_direct_no_semantic(input_list_layout);
|
||||||
|
|
||||||
let caller = self.debug_symbol("caller");
|
let caller = self.debug_symbol("caller");
|
||||||
let data = self.debug_symbol("data");
|
let data = self.debug_symbol("data");
|
||||||
|
@ -2256,7 +2257,7 @@ impl<
|
||||||
.claim_stack_area(dst, self.layout_interner.stack_size(*ret_layout));
|
.claim_stack_area(dst, self.layout_interner.stack_size(*ret_layout));
|
||||||
|
|
||||||
let ret_fields =
|
let ret_fields =
|
||||||
if let LayoutRepr::Struct(field_layouts) = self.layout_interner.get(*ret_layout).repr {
|
if let LayoutRepr::Struct(field_layouts) = self.layout_interner.get_repr(*ret_layout) {
|
||||||
field_layouts
|
field_layouts
|
||||||
} else {
|
} else {
|
||||||
internal_error!(
|
internal_error!(
|
||||||
|
@ -2478,7 +2479,7 @@ impl<
|
||||||
element_in_layout: &InLayout<'a>,
|
element_in_layout: &InLayout<'a>,
|
||||||
elements: &[ListLiteralElement<'a>],
|
elements: &[ListLiteralElement<'a>],
|
||||||
) {
|
) {
|
||||||
let element_layout = self.layout_interner.get(*element_in_layout);
|
let element_layout = self.layout_interner.get_repr(*element_in_layout);
|
||||||
let element_width = self.layout_interner.stack_size(*element_in_layout) as u64;
|
let element_width = self.layout_interner.stack_size(*element_in_layout) as u64;
|
||||||
|
|
||||||
// load the total size of the data we want to store (excludes refcount)
|
// load the total size of the data we want to store (excludes refcount)
|
||||||
|
@ -2677,7 +2678,7 @@ impl<
|
||||||
_ => {
|
_ => {
|
||||||
let union_in_layout = self
|
let union_in_layout = self
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.insert_no_semantic(LayoutRepr::Union(*union_layout));
|
.insert_direct_no_semantic(LayoutRepr::Union(*union_layout));
|
||||||
todo!(
|
todo!(
|
||||||
"loading from union type: {:?}",
|
"loading from union type: {:?}",
|
||||||
self.layout_interner.dbg(union_in_layout)
|
self.layout_interner.dbg(union_in_layout)
|
||||||
|
@ -2700,7 +2701,7 @@ impl<
|
||||||
let element_width = self.layout_interner.stack_size(element_layout) as u64;
|
let element_width = self.layout_interner.stack_size(element_layout) as u64;
|
||||||
let element_offset = 0;
|
let element_offset = 0;
|
||||||
|
|
||||||
let layout = self.layout_interner.get(element_layout);
|
let layout = self.layout_interner.get_repr(element_layout);
|
||||||
|
|
||||||
Self::ptr_write(
|
Self::ptr_write(
|
||||||
&mut self.buf,
|
&mut self.buf,
|
||||||
|
@ -2958,7 +2959,7 @@ impl<
|
||||||
let temp_sym = Symbol::DEV_TMP5;
|
let temp_sym = Symbol::DEV_TMP5;
|
||||||
let layout = self
|
let layout = self
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.insert_no_semantic(LayoutRepr::Struct(other_fields));
|
.insert_direct_no_semantic(LayoutRepr::Struct(other_fields));
|
||||||
|
|
||||||
self.load_literal_symbols(fields);
|
self.load_literal_symbols(fields);
|
||||||
self.storage_manager.create_struct(
|
self.storage_manager.create_struct(
|
||||||
|
@ -2995,7 +2996,7 @@ impl<
|
||||||
let temp_sym = Symbol::DEV_TMP5;
|
let temp_sym = Symbol::DEV_TMP5;
|
||||||
let layout = self
|
let layout = self
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.insert_no_semantic(LayoutRepr::Struct(other_fields));
|
.insert_direct_no_semantic(LayoutRepr::Struct(other_fields));
|
||||||
|
|
||||||
self.load_literal_symbols(fields);
|
self.load_literal_symbols(fields);
|
||||||
self.storage_manager.create_struct(
|
self.storage_manager.create_struct(
|
||||||
|
@ -3042,13 +3043,13 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_literal(&mut self, sym: &Symbol, layout: &InLayout<'a>, lit: &Literal<'a>) {
|
fn load_literal(&mut self, sym: &Symbol, layout: &InLayout<'a>, lit: &Literal<'a>) {
|
||||||
let layout = self.layout_interner.get(*layout);
|
let layout = self.layout_interner.get_repr(*layout);
|
||||||
|
|
||||||
if let LayoutRepr::LambdaSet(lambda_set) = layout.repr {
|
if let LayoutRepr::LambdaSet(lambda_set) = layout {
|
||||||
return self.load_literal(sym, &lambda_set.runtime_representation(), lit);
|
return self.load_literal(sym, &lambda_set.runtime_representation(), lit);
|
||||||
}
|
}
|
||||||
|
|
||||||
match (lit, layout.repr) {
|
match (lit, layout) {
|
||||||
(
|
(
|
||||||
Literal::Int(x),
|
Literal::Int(x),
|
||||||
LayoutRepr::Builtin(Builtin::Int(
|
LayoutRepr::Builtin(Builtin::Int(
|
||||||
|
@ -3176,7 +3177,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn return_symbol(&mut self, sym: &Symbol, layout: &InLayout<'a>) {
|
fn return_symbol(&mut self, sym: &Symbol, layout: &InLayout<'a>) {
|
||||||
let repr = self.layout_interner.get(*layout).repr;
|
let repr = self.layout_interner.get_repr(*layout);
|
||||||
if self.storage_manager.is_stored_primitive(sym) {
|
if self.storage_manager.is_stored_primitive(sym) {
|
||||||
// Just load it to the correct type of reg as a stand alone value.
|
// Just load it to the correct type of reg as a stand alone value.
|
||||||
match repr {
|
match repr {
|
||||||
|
@ -3547,7 +3548,7 @@ impl<
|
||||||
src2: &Symbol,
|
src2: &Symbol,
|
||||||
arg_layout: &InLayout<'a>,
|
arg_layout: &InLayout<'a>,
|
||||||
) {
|
) {
|
||||||
match self.interner().get(*arg_layout).repr {
|
match self.interner().get_repr(*arg_layout) {
|
||||||
single_register_integers!() => {
|
single_register_integers!() => {
|
||||||
let buf = &mut self.buf;
|
let buf = &mut self.buf;
|
||||||
|
|
||||||
|
@ -3749,7 +3750,7 @@ impl<
|
||||||
element_in_layout: InLayout<'a>,
|
element_in_layout: InLayout<'a>,
|
||||||
dst: Symbol,
|
dst: Symbol,
|
||||||
) {
|
) {
|
||||||
match layout_interner.get(element_in_layout).repr {
|
match layout_interner.get_repr(element_in_layout) {
|
||||||
LayoutRepr::Builtin(builtin) => match builtin {
|
LayoutRepr::Builtin(builtin) => match builtin {
|
||||||
Builtin::Int(int_width) => match int_width {
|
Builtin::Int(int_width) => match int_width {
|
||||||
IntWidth::I128 | IntWidth::U128 => {
|
IntWidth::I128 | IntWidth::U128 => {
|
||||||
|
@ -3865,10 +3866,10 @@ impl<
|
||||||
ptr_reg: GeneralReg,
|
ptr_reg: GeneralReg,
|
||||||
element_offset: i32,
|
element_offset: i32,
|
||||||
element_width: u64,
|
element_width: u64,
|
||||||
element_layout: Layout<'a>,
|
element_layout: LayoutRepr<'a>,
|
||||||
value: Symbol,
|
value: Symbol,
|
||||||
) {
|
) {
|
||||||
match element_layout.repr {
|
match element_layout {
|
||||||
LayoutRepr::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
|
LayoutRepr::Builtin(Builtin::Int(IntWidth::I64 | IntWidth::U64)) => {
|
||||||
let sym_reg = storage_manager.load_to_general_reg(buf, &value);
|
let sym_reg = storage_manager.load_to_general_reg(buf, &value);
|
||||||
ASM::mov_mem64_offset32_reg64(buf, ptr_reg, element_offset, sym_reg);
|
ASM::mov_mem64_offset32_reg64(buf, ptr_reg, element_offset, sym_reg);
|
||||||
|
@ -3894,7 +3895,7 @@ impl<
|
||||||
ASM::mov_mem64_offset32_reg64(buf, ptr_reg, element_offset, sym_reg);
|
ASM::mov_mem64_offset32_reg64(buf, ptr_reg, element_offset, sym_reg);
|
||||||
}
|
}
|
||||||
LayoutRepr::LambdaSet(lambda_set) => {
|
LayoutRepr::LambdaSet(lambda_set) => {
|
||||||
let layout = layout_interner.get(lambda_set.runtime_representation());
|
let repr = layout_interner.get_repr(lambda_set.runtime_representation());
|
||||||
|
|
||||||
Self::ptr_write(
|
Self::ptr_write(
|
||||||
buf,
|
buf,
|
||||||
|
@ -3903,7 +3904,7 @@ impl<
|
||||||
ptr_reg,
|
ptr_reg,
|
||||||
element_offset,
|
element_offset,
|
||||||
element_width,
|
element_width,
|
||||||
layout,
|
repr,
|
||||||
value,
|
value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -665,7 +665,7 @@ impl<
|
||||||
|
|
||||||
let mut in_layout = *layout;
|
let mut in_layout = *layout;
|
||||||
let layout = loop {
|
let layout = loop {
|
||||||
match layout_interner.get(in_layout).repr {
|
match layout_interner.get_repr(in_layout) {
|
||||||
LayoutRepr::LambdaSet(inner) => in_layout = inner.runtime_representation(),
|
LayoutRepr::LambdaSet(inner) => in_layout = inner.runtime_representation(),
|
||||||
other => break other,
|
other => break other,
|
||||||
}
|
}
|
||||||
|
@ -728,7 +728,7 @@ impl<
|
||||||
sym: &Symbol,
|
sym: &Symbol,
|
||||||
layout: &InLayout<'a>,
|
layout: &InLayout<'a>,
|
||||||
) {
|
) {
|
||||||
match layout_interner.get(*layout).repr {
|
match layout_interner.get_repr(*layout) {
|
||||||
LayoutRepr::Builtin(builtin) => match builtin {
|
LayoutRepr::Builtin(builtin) => match builtin {
|
||||||
Builtin::Int(int_width) => match int_width {
|
Builtin::Int(int_width) => match int_width {
|
||||||
IntWidth::I128 | IntWidth::U128 => {
|
IntWidth::I128 | IntWidth::U128 => {
|
||||||
|
@ -1104,7 +1104,7 @@ impl<
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
layout: InLayout<'a>,
|
layout: InLayout<'a>,
|
||||||
) {
|
) {
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get_repr(layout) {
|
||||||
single_register_layouts!() | pointer_layouts!() => {
|
single_register_layouts!() | pointer_layouts!() => {
|
||||||
let base_offset = self.claim_stack_size(8);
|
let base_offset = self.claim_stack_size(8);
|
||||||
self.symbol_storage_map.insert(
|
self.symbol_storage_map.insert(
|
||||||
|
@ -1169,7 +1169,7 @@ impl<
|
||||||
layout: InLayout<'a>,
|
layout: InLayout<'a>,
|
||||||
base_offset: i32,
|
base_offset: i32,
|
||||||
) {
|
) {
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get_repr(layout) {
|
||||||
single_register_integers!() | pointer_layouts!() => {
|
single_register_integers!() | pointer_layouts!() => {
|
||||||
let reg = self.load_to_general_reg(buf, &symbol);
|
let reg = self.load_to_general_reg(buf, &symbol);
|
||||||
ASM::mov_base32_reg64(buf, base_offset, reg);
|
ASM::mov_base32_reg64(buf, base_offset, reg);
|
||||||
|
@ -1491,7 +1491,7 @@ impl<
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_primitive(layout_interner: &mut STLayoutInterner<'_>, layout: InLayout<'_>) -> bool {
|
fn is_primitive(layout_interner: &mut STLayoutInterner<'_>, layout: InLayout<'_>) -> bool {
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get_repr(layout) {
|
||||||
single_register_layouts!() => true,
|
single_register_layouts!() => true,
|
||||||
pointer_layouts!() => true,
|
pointer_layouts!() => true,
|
||||||
LayoutRepr::LambdaSet(lambda_set) => {
|
LayoutRepr::LambdaSet(lambda_set) => {
|
||||||
|
|
|
@ -346,7 +346,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Syste
|
||||||
sym: &Symbol,
|
sym: &Symbol,
|
||||||
layout: &InLayout<'a>,
|
layout: &InLayout<'a>,
|
||||||
) {
|
) {
|
||||||
match layout_interner.get(*layout).repr {
|
match layout_interner.get_repr(*layout) {
|
||||||
single_register_layouts!() => {
|
single_register_layouts!() => {
|
||||||
internal_error!("single register layouts are not complex symbols");
|
internal_error!("single register layouts are not complex symbols");
|
||||||
}
|
}
|
||||||
|
@ -404,7 +404,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Syste
|
||||||
sym: &Symbol,
|
sym: &Symbol,
|
||||||
layout: &InLayout<'a>,
|
layout: &InLayout<'a>,
|
||||||
) {
|
) {
|
||||||
match layout_interner.get(*layout).repr {
|
match layout_interner.get_repr(*layout) {
|
||||||
single_register_layouts!() => {
|
single_register_layouts!() => {
|
||||||
internal_error!("single register layouts are not complex symbols");
|
internal_error!("single register layouts are not complex symbols");
|
||||||
}
|
}
|
||||||
|
@ -459,7 +459,7 @@ impl X64_64SystemVStoreArgs {
|
||||||
sym: Symbol,
|
sym: Symbol,
|
||||||
in_layout: InLayout<'a>,
|
in_layout: InLayout<'a>,
|
||||||
) {
|
) {
|
||||||
match layout_interner.get(in_layout).repr {
|
match layout_interner.get_repr(in_layout) {
|
||||||
single_register_integers!() => self.store_arg_general(buf, storage_manager, sym),
|
single_register_integers!() => self.store_arg_general(buf, storage_manager, sym),
|
||||||
pointer_layouts!() => self.store_arg_general(buf, storage_manager, sym),
|
pointer_layouts!() => self.store_arg_general(buf, storage_manager, sym),
|
||||||
single_register_floats!() => self.store_arg_float(buf, storage_manager, sym),
|
single_register_floats!() => self.store_arg_float(buf, storage_manager, sym),
|
||||||
|
@ -654,7 +654,7 @@ impl X64_64SystemVLoadArgs {
|
||||||
in_layout: InLayout<'a>,
|
in_layout: InLayout<'a>,
|
||||||
) {
|
) {
|
||||||
let stack_size = layout_interner.stack_size(in_layout);
|
let stack_size = layout_interner.stack_size(in_layout);
|
||||||
match layout_interner.get(in_layout).repr {
|
match layout_interner.get_repr(in_layout) {
|
||||||
single_register_integers!() => self.load_arg_general(storage_manager, sym),
|
single_register_integers!() => self.load_arg_general(storage_manager, sym),
|
||||||
pointer_layouts!() => self.load_arg_general(storage_manager, sym),
|
pointer_layouts!() => self.load_arg_general(storage_manager, sym),
|
||||||
single_register_floats!() => self.load_arg_float(storage_manager, sym),
|
single_register_floats!() => self.load_arg_float(storage_manager, sym),
|
||||||
|
@ -885,7 +885,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Windo
|
||||||
}
|
}
|
||||||
|
|
||||||
for (layout, sym) in args.iter() {
|
for (layout, sym) in args.iter() {
|
||||||
match layout_interner.get(*layout).repr {
|
match layout_interner.get_repr(*layout) {
|
||||||
single_register_integers!() => {
|
single_register_integers!() => {
|
||||||
match Self::GENERAL_PARAM_REGS.get(general_registers_used) {
|
match Self::GENERAL_PARAM_REGS.get(general_registers_used) {
|
||||||
Some(reg) => {
|
Some(reg) => {
|
||||||
|
@ -946,7 +946,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Windo
|
||||||
let mut float_registers_used = 0;
|
let mut float_registers_used = 0;
|
||||||
|
|
||||||
for (sym, layout) in args.iter().zip(arg_layouts.iter()) {
|
for (sym, layout) in args.iter().zip(arg_layouts.iter()) {
|
||||||
match layout_interner.get(*layout).repr {
|
match layout_interner.get_repr(*layout) {
|
||||||
single_register_integers!() => {
|
single_register_integers!() => {
|
||||||
match Self::GENERAL_PARAM_REGS.get(general_registers_used) {
|
match Self::GENERAL_PARAM_REGS.get(general_registers_used) {
|
||||||
Some(reg) => {
|
Some(reg) => {
|
||||||
|
|
|
@ -360,7 +360,7 @@ trait Backend<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_argument(&mut self, list_layout: InLayout<'a>) -> ListArgument<'a> {
|
fn list_argument(&mut self, list_layout: InLayout<'a>) -> ListArgument<'a> {
|
||||||
let element_layout = match self.interner().get(list_layout).repr {
|
let element_layout = match self.interner().get_repr(list_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::List(e)) => e,
|
LayoutRepr::Builtin(Builtin::List(e)) => e,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
@ -384,7 +384,7 @@ trait Backend<'a> {
|
||||||
fn increment_fn_pointer(&mut self, layout: InLayout<'a>) -> Symbol {
|
fn increment_fn_pointer(&mut self, layout: InLayout<'a>) -> Symbol {
|
||||||
let box_layout = self
|
let box_layout = self
|
||||||
.interner_mut()
|
.interner_mut()
|
||||||
.insert_no_semantic(LayoutRepr::Boxed(layout));
|
.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
|
||||||
|
|
||||||
let element_increment = self.debug_symbol("element_increment");
|
let element_increment = self.debug_symbol("element_increment");
|
||||||
let element_increment_symbol = self.build_indirect_inc(layout);
|
let element_increment_symbol = self.build_indirect_inc(layout);
|
||||||
|
@ -404,7 +404,7 @@ trait Backend<'a> {
|
||||||
fn decrement_fn_pointer(&mut self, layout: InLayout<'a>) -> Symbol {
|
fn decrement_fn_pointer(&mut self, layout: InLayout<'a>) -> Symbol {
|
||||||
let box_layout = self
|
let box_layout = self
|
||||||
.interner_mut()
|
.interner_mut()
|
||||||
.insert_no_semantic(LayoutRepr::Boxed(layout));
|
.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
|
||||||
|
|
||||||
let element_decrement = self.debug_symbol("element_decrement");
|
let element_decrement = self.debug_symbol("element_decrement");
|
||||||
let element_decrement_symbol = self.build_indirect_dec(layout);
|
let element_decrement_symbol = self.build_indirect_dec(layout);
|
||||||
|
@ -801,7 +801,7 @@ trait Backend<'a> {
|
||||||
self.tag(sym, arguments, tag_layout, *tag_id, None);
|
self.tag(sym, arguments, tag_layout, *tag_id, None);
|
||||||
}
|
}
|
||||||
Expr::ExprBox { symbol: value } => {
|
Expr::ExprBox { symbol: value } => {
|
||||||
let element_layout = match self.interner().get(*layout).repr {
|
let element_layout = match self.interner().get_repr(*layout) {
|
||||||
LayoutRepr::Boxed(boxed) => boxed,
|
LayoutRepr::Boxed(boxed) => boxed,
|
||||||
_ => unreachable!("{:?}", self.interner().dbg(*layout)),
|
_ => unreachable!("{:?}", self.interner().dbg(*layout)),
|
||||||
};
|
};
|
||||||
|
@ -1030,7 +1030,7 @@ trait Backend<'a> {
|
||||||
);
|
);
|
||||||
self.build_num_sub_wrap(sym, &args[0], &args[1], ret_layout)
|
self.build_num_sub_wrap(sym, &args[0], &args[1], ret_layout)
|
||||||
}
|
}
|
||||||
LowLevel::NumSubSaturated => match self.interner().get(*ret_layout).repr {
|
LowLevel::NumSubSaturated => match self.interner().get_repr(*ret_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => self.build_fn_call(
|
LayoutRepr::Builtin(Builtin::Int(int_width)) => self.build_fn_call(
|
||||||
sym,
|
sym,
|
||||||
bitcode::NUM_SUB_SATURATED_INT[int_width].to_string(),
|
bitcode::NUM_SUB_SATURATED_INT[int_width].to_string(),
|
||||||
|
@ -1053,7 +1053,7 @@ trait Backend<'a> {
|
||||||
},
|
},
|
||||||
LowLevel::NumBitwiseAnd => {
|
LowLevel::NumBitwiseAnd => {
|
||||||
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
||||||
self.interner().get(*ret_layout).repr
|
self.interner().get_repr(*ret_layout)
|
||||||
{
|
{
|
||||||
self.build_int_bitwise_and(sym, &args[0], &args[1], int_width)
|
self.build_int_bitwise_and(sym, &args[0], &args[1], int_width)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1062,7 +1062,7 @@ trait Backend<'a> {
|
||||||
}
|
}
|
||||||
LowLevel::NumBitwiseOr => {
|
LowLevel::NumBitwiseOr => {
|
||||||
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
||||||
self.interner().get(*ret_layout).repr
|
self.interner().get_repr(*ret_layout)
|
||||||
{
|
{
|
||||||
self.build_int_bitwise_or(sym, &args[0], &args[1], int_width)
|
self.build_int_bitwise_or(sym, &args[0], &args[1], int_width)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1071,7 +1071,7 @@ trait Backend<'a> {
|
||||||
}
|
}
|
||||||
LowLevel::NumBitwiseXor => {
|
LowLevel::NumBitwiseXor => {
|
||||||
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
||||||
self.interner().get(*ret_layout).repr
|
self.interner().get_repr(*ret_layout)
|
||||||
{
|
{
|
||||||
self.build_int_bitwise_xor(sym, &args[0], &args[1], int_width)
|
self.build_int_bitwise_xor(sym, &args[0], &args[1], int_width)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1079,14 +1079,14 @@ trait Backend<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LowLevel::And => {
|
LowLevel::And => {
|
||||||
if let LayoutRepr::Builtin(Builtin::Bool) = self.interner().get(*ret_layout).repr {
|
if let LayoutRepr::Builtin(Builtin::Bool) = self.interner().get_repr(*ret_layout) {
|
||||||
self.build_int_bitwise_and(sym, &args[0], &args[1], IntWidth::U8)
|
self.build_int_bitwise_and(sym, &args[0], &args[1], IntWidth::U8)
|
||||||
} else {
|
} else {
|
||||||
internal_error!("bitwise and on a non-integer")
|
internal_error!("bitwise and on a non-integer")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LowLevel::Or => {
|
LowLevel::Or => {
|
||||||
if let LayoutRepr::Builtin(Builtin::Bool) = self.interner().get(*ret_layout).repr {
|
if let LayoutRepr::Builtin(Builtin::Bool) = self.interner().get_repr(*ret_layout) {
|
||||||
self.build_int_bitwise_or(sym, &args[0], &args[1], IntWidth::U8)
|
self.build_int_bitwise_or(sym, &args[0], &args[1], IntWidth::U8)
|
||||||
} else {
|
} else {
|
||||||
internal_error!("bitwise or on a non-integer")
|
internal_error!("bitwise or on a non-integer")
|
||||||
|
@ -1094,7 +1094,7 @@ trait Backend<'a> {
|
||||||
}
|
}
|
||||||
LowLevel::NumShiftLeftBy => {
|
LowLevel::NumShiftLeftBy => {
|
||||||
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
||||||
self.interner().get(*ret_layout).repr
|
self.interner().get_repr(*ret_layout)
|
||||||
{
|
{
|
||||||
self.build_int_shift_left(sym, &args[0], &args[1], int_width)
|
self.build_int_shift_left(sym, &args[0], &args[1], int_width)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1103,7 +1103,7 @@ trait Backend<'a> {
|
||||||
}
|
}
|
||||||
LowLevel::NumShiftRightBy => {
|
LowLevel::NumShiftRightBy => {
|
||||||
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
||||||
self.interner().get(*ret_layout).repr
|
self.interner().get_repr(*ret_layout)
|
||||||
{
|
{
|
||||||
self.build_int_shift_right(sym, &args[0], &args[1], int_width)
|
self.build_int_shift_right(sym, &args[0], &args[1], int_width)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1112,7 +1112,7 @@ trait Backend<'a> {
|
||||||
}
|
}
|
||||||
LowLevel::NumShiftRightZfBy => {
|
LowLevel::NumShiftRightZfBy => {
|
||||||
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
if let LayoutRepr::Builtin(Builtin::Int(int_width)) =
|
||||||
self.interner().get(*ret_layout).repr
|
self.interner().get_repr(*ret_layout)
|
||||||
{
|
{
|
||||||
self.build_int_shift_right_zero_fill(sym, &args[0], &args[1], int_width)
|
self.build_int_shift_right_zero_fill(sym, &args[0], &args[1], int_width)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1523,13 +1523,13 @@ trait Backend<'a> {
|
||||||
ret_layout,
|
ret_layout,
|
||||||
),
|
),
|
||||||
LowLevel::StrToNum => {
|
LowLevel::StrToNum => {
|
||||||
let number_layout = match self.interner().get(*ret_layout).repr {
|
let number_layout = match self.interner().get_repr(*ret_layout) {
|
||||||
LayoutRepr::Struct(field_layouts) => field_layouts[0], // TODO: why is it sometimes a struct?
|
LayoutRepr::Struct(field_layouts) => field_layouts[0], // TODO: why is it sometimes a struct?
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// match on the return layout to figure out which zig builtin we need
|
// match on the return layout to figure out which zig builtin we need
|
||||||
let intrinsic = match self.interner().get(number_layout).repr {
|
let intrinsic = match self.interner().get_repr(number_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => &bitcode::STR_TO_INT[int_width],
|
LayoutRepr::Builtin(Builtin::Int(int_width)) => &bitcode::STR_TO_INT[int_width],
|
||||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
||||||
&bitcode::STR_TO_FLOAT[float_width]
|
&bitcode::STR_TO_FLOAT[float_width]
|
||||||
|
@ -1549,7 +1549,7 @@ trait Backend<'a> {
|
||||||
self.build_ptr_cast(sym, &args[0])
|
self.build_ptr_cast(sym, &args[0])
|
||||||
}
|
}
|
||||||
LowLevel::PtrWrite => {
|
LowLevel::PtrWrite => {
|
||||||
let element_layout = match self.interner().get(*ret_layout).repr {
|
let element_layout = match self.interner().get_repr(*ret_layout) {
|
||||||
LayoutRepr::Boxed(boxed) => boxed,
|
LayoutRepr::Boxed(boxed) => boxed,
|
||||||
_ => unreachable!("cannot write to {:?}", self.interner().dbg(*ret_layout)),
|
_ => unreachable!("cannot write to {:?}", self.interner().dbg(*ret_layout)),
|
||||||
};
|
};
|
||||||
|
@ -1600,7 +1600,7 @@ trait Backend<'a> {
|
||||||
),
|
),
|
||||||
LowLevel::NumToStr => {
|
LowLevel::NumToStr => {
|
||||||
let arg_layout = arg_layouts[0];
|
let arg_layout = arg_layouts[0];
|
||||||
let intrinsic = match self.interner().get(arg_layout).repr {
|
let intrinsic = match self.interner().get_repr(arg_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => &bitcode::STR_FROM_INT[width],
|
LayoutRepr::Builtin(Builtin::Int(width)) => &bitcode::STR_FROM_INT[width],
|
||||||
LayoutRepr::Builtin(Builtin::Float(width)) => &bitcode::STR_FROM_FLOAT[width],
|
LayoutRepr::Builtin(Builtin::Float(width)) => &bitcode::STR_FROM_FLOAT[width],
|
||||||
LayoutRepr::Builtin(Builtin::Decimal) => bitcode::DEC_TO_STR,
|
LayoutRepr::Builtin(Builtin::Decimal) => bitcode::DEC_TO_STR,
|
||||||
|
@ -1614,12 +1614,12 @@ trait Backend<'a> {
|
||||||
self.build_fn_call(sym, intrinsic, args, arg_layouts, ret_layout);
|
self.build_fn_call(sym, intrinsic, args, arg_layouts, ret_layout);
|
||||||
}
|
}
|
||||||
LowLevel::NumIntCast => {
|
LowLevel::NumIntCast => {
|
||||||
let source_width = match self.interner().get(arg_layouts[0]).repr {
|
let source_width = match self.interner().get_repr(arg_layouts[0]) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => width,
|
LayoutRepr::Builtin(Builtin::Int(width)) => width,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let target_width = match self.interner().get(*ret_layout).repr {
|
let target_width = match self.interner().get_repr(*ret_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => width,
|
LayoutRepr::Builtin(Builtin::Int(width)) => width,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -464,7 +464,7 @@ fn build_exposed_generic_proc<'a, B: Backend<'a>>(backend: &mut B, proc: &Proc<'
|
||||||
|
|
||||||
let box_layout = backend
|
let box_layout = backend
|
||||||
.interner_mut()
|
.interner_mut()
|
||||||
.insert_no_semantic(roc_mono::layout::LayoutRepr::Boxed(proc.ret_layout));
|
.insert_direct_no_semantic(roc_mono::layout::LayoutRepr::Boxed(proc.ret_layout));
|
||||||
|
|
||||||
let mut args = bumpalo::collections::Vec::new_in(arena);
|
let mut args = bumpalo::collections::Vec::new_in(arena);
|
||||||
args.extend(proc.args);
|
args.extend(proc.args);
|
||||||
|
|
|
@ -610,7 +610,7 @@ pub fn build_compare_wrapper<'a, 'ctx>(
|
||||||
|
|
||||||
let closure_data_repr = closure_data_layout.runtime_representation();
|
let closure_data_repr = closure_data_layout.runtime_representation();
|
||||||
|
|
||||||
let arguments_cast = match layout_interner.get(closure_data_repr).repr {
|
let arguments_cast = match layout_interner.get_repr(closure_data_repr) {
|
||||||
LayoutRepr::Struct(&[]) => {
|
LayoutRepr::Struct(&[]) => {
|
||||||
// nothing to add
|
// nothing to add
|
||||||
&default
|
&default
|
||||||
|
|
|
@ -783,7 +783,7 @@ pub fn build_exp_literal<'a, 'ctx>(
|
||||||
use roc_mono::ir::Literal::*;
|
use roc_mono::ir::Literal::*;
|
||||||
|
|
||||||
match literal {
|
match literal {
|
||||||
Int(bytes) => match layout_interner.get(layout).repr {
|
Int(bytes) => match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Bool) => env
|
LayoutRepr::Builtin(Builtin::Bool) => env
|
||||||
.context
|
.context
|
||||||
.bool_type()
|
.bool_type()
|
||||||
|
@ -797,7 +797,7 @@ pub fn build_exp_literal<'a, 'ctx>(
|
||||||
|
|
||||||
U128(bytes) => const_u128(env, u128::from_ne_bytes(*bytes)).into(),
|
U128(bytes) => const_u128(env, u128::from_ne_bytes(*bytes)).into(),
|
||||||
|
|
||||||
Float(float) => match layout_interner.get(layout).repr {
|
Float(float) => match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
||||||
float_with_precision(env, *float, float_width)
|
float_with_precision(env, *float, float_width)
|
||||||
}
|
}
|
||||||
|
@ -1178,7 +1178,7 @@ pub fn build_exp_expr<'a, 'ctx>(
|
||||||
let tag_ptr = tag_ptr.into_pointer_value();
|
let tag_ptr = tag_ptr.into_pointer_value();
|
||||||
|
|
||||||
// reset is only generated for union values
|
// reset is only generated for union values
|
||||||
let union_layout = match layout_interner.get(layout).repr {
|
let union_layout = match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Union(ul) => ul,
|
LayoutRepr::Union(ul) => ul,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
@ -1323,7 +1323,7 @@ pub fn build_exp_expr<'a, 'ctx>(
|
||||||
} => {
|
} => {
|
||||||
let (value, layout) = load_symbol_and_layout(scope, structure);
|
let (value, layout) = load_symbol_and_layout(scope, structure);
|
||||||
|
|
||||||
let layout = if let LayoutRepr::LambdaSet(lambda_set) = layout_interner.get(layout).repr
|
let layout = if let LayoutRepr::LambdaSet(lambda_set) = layout_interner.get_repr(layout)
|
||||||
{
|
{
|
||||||
lambda_set.runtime_representation()
|
lambda_set.runtime_representation()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1331,7 +1331,7 @@ pub fn build_exp_expr<'a, 'ctx>(
|
||||||
};
|
};
|
||||||
|
|
||||||
// extract field from a record
|
// extract field from a record
|
||||||
match (value, layout_interner.get(layout).repr) {
|
match (value, layout_interner.get_repr(layout)) {
|
||||||
(StructValue(argument), LayoutRepr::Struct(field_layouts)) => {
|
(StructValue(argument), LayoutRepr::Struct(field_layouts)) => {
|
||||||
debug_assert!(!field_layouts.is_empty());
|
debug_assert!(!field_layouts.is_empty());
|
||||||
|
|
||||||
|
@ -1385,8 +1385,8 @@ pub fn build_exp_expr<'a, 'ctx>(
|
||||||
|
|
||||||
let field_layouts = tag_layouts[*tag_id as usize];
|
let field_layouts = tag_layouts[*tag_id as usize];
|
||||||
|
|
||||||
let struct_layout =
|
let struct_layout = layout_interner
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||||
let struct_type = basic_type_from_layout(env, layout_interner, struct_layout);
|
let struct_type = basic_type_from_layout(env, layout_interner, struct_layout);
|
||||||
|
|
||||||
let opaque_data_ptr = env
|
let opaque_data_ptr = env
|
||||||
|
@ -1442,8 +1442,8 @@ pub fn build_exp_expr<'a, 'ctx>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
UnionLayout::NonNullableUnwrapped(field_layouts) => {
|
UnionLayout::NonNullableUnwrapped(field_layouts) => {
|
||||||
let struct_layout =
|
let struct_layout = layout_interner
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||||
|
|
||||||
let struct_type = basic_type_from_layout(env, layout_interner, struct_layout);
|
let struct_type = basic_type_from_layout(env, layout_interner, struct_layout);
|
||||||
let target_loaded_type = basic_type_from_layout(env, layout_interner, layout);
|
let target_loaded_type = basic_type_from_layout(env, layout_interner, layout);
|
||||||
|
@ -1493,8 +1493,8 @@ pub fn build_exp_expr<'a, 'ctx>(
|
||||||
debug_assert_ne!(*tag_id != 0, *nullable_id);
|
debug_assert_ne!(*tag_id != 0, *nullable_id);
|
||||||
|
|
||||||
let field_layouts = other_fields;
|
let field_layouts = other_fields;
|
||||||
let struct_layout =
|
let struct_layout = layout_interner
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||||
|
|
||||||
let struct_type = basic_type_from_layout(env, layout_interner, struct_layout);
|
let struct_type = basic_type_from_layout(env, layout_interner, struct_layout);
|
||||||
let target_loaded_type = basic_type_from_layout(env, layout_interner, layout);
|
let target_loaded_type = basic_type_from_layout(env, layout_interner, layout);
|
||||||
|
@ -1625,7 +1625,7 @@ fn build_tag_field_value<'a, 'ctx>(
|
||||||
value: BasicValueEnum<'ctx>,
|
value: BasicValueEnum<'ctx>,
|
||||||
tag_field_layout: InLayout<'a>,
|
tag_field_layout: InLayout<'a>,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
if let LayoutRepr::RecursivePointer(_) = layout_interner.get(tag_field_layout).repr {
|
if let LayoutRepr::RecursivePointer(_) = layout_interner.get_repr(tag_field_layout) {
|
||||||
debug_assert!(value.is_pointer_value());
|
debug_assert!(value.is_pointer_value());
|
||||||
|
|
||||||
// we store recursive pointers as `i64*`
|
// we store recursive pointers as `i64*`
|
||||||
|
@ -1696,7 +1696,10 @@ fn build_struct<'a, 'ctx>(
|
||||||
// Zero-sized fields have no runtime representation.
|
// Zero-sized fields have no runtime representation.
|
||||||
// The layout of the struct expects them to be dropped!
|
// The layout of the struct expects them to be dropped!
|
||||||
let (field_expr, field_layout) = load_symbol_and_layout(scope, symbol);
|
let (field_expr, field_layout) = load_symbol_and_layout(scope, symbol);
|
||||||
if !layout_interner.get(field_layout).is_dropped_because_empty() {
|
if !layout_interner
|
||||||
|
.get_repr(field_layout)
|
||||||
|
.is_dropped_because_empty()
|
||||||
|
{
|
||||||
let field_type = basic_type_from_layout(env, layout_interner, field_layout);
|
let field_type = basic_type_from_layout(env, layout_interner, field_layout);
|
||||||
field_types.push(field_type);
|
field_types.push(field_type);
|
||||||
|
|
||||||
|
@ -1780,8 +1783,8 @@ fn build_tag<'a, 'ctx>(
|
||||||
use std::cmp::Ordering::*;
|
use std::cmp::Ordering::*;
|
||||||
match tag_id.cmp(&(*nullable_id as _)) {
|
match tag_id.cmp(&(*nullable_id as _)) {
|
||||||
Equal => {
|
Equal => {
|
||||||
let layout =
|
let layout = layout_interner
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::Union(*union_layout));
|
.insert_direct_no_semantic(LayoutRepr::Union(*union_layout));
|
||||||
|
|
||||||
return basic_type_from_layout(env, layout_interner, layout)
|
return basic_type_from_layout(env, layout_interner, layout)
|
||||||
.into_pointer_type()
|
.into_pointer_type()
|
||||||
|
@ -2133,7 +2136,8 @@ fn lookup_at_index_ptr2<'a, 'ctx>(
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
|
|
||||||
let struct_layout = layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
let struct_layout =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||||
let struct_type =
|
let struct_type =
|
||||||
basic_type_from_layout(env, layout_interner, struct_layout).into_struct_type();
|
basic_type_from_layout(env, layout_interner, struct_layout).into_struct_type();
|
||||||
|
|
||||||
|
@ -2545,7 +2549,7 @@ pub fn build_exp_stmt<'a, 'ctx>(
|
||||||
|
|
||||||
for (symbol, expr, layout) in queue {
|
for (symbol, expr, layout) in queue {
|
||||||
debug_assert!(!matches!(
|
debug_assert!(!matches!(
|
||||||
layout_interner.get(*layout).repr,
|
layout_interner.get_repr(*layout),
|
||||||
LayoutRepr::RecursivePointer(_)
|
LayoutRepr::RecursivePointer(_)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -2845,12 +2849,12 @@ pub fn build_exp_stmt<'a, 'ctx>(
|
||||||
DecRef(symbol) => {
|
DecRef(symbol) => {
|
||||||
let (value, layout) = load_symbol_and_layout(scope, symbol);
|
let (value, layout) = load_symbol_and_layout(scope, symbol);
|
||||||
|
|
||||||
let lay = layout_interner.get(layout);
|
let lay = layout_interner.get_repr(layout);
|
||||||
match lay.repr {
|
match lay {
|
||||||
LayoutRepr::Builtin(Builtin::Str) => todo!(),
|
LayoutRepr::Builtin(Builtin::Str) => todo!(),
|
||||||
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
|
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
|
||||||
debug_assert!(value.is_struct_value());
|
debug_assert!(value.is_struct_value());
|
||||||
let element_layout = layout_interner.get(element_layout);
|
let element_layout = layout_interner.get_repr(element_layout);
|
||||||
let alignment =
|
let alignment =
|
||||||
element_layout.alignment_bytes(layout_interner, env.target_info);
|
element_layout.alignment_bytes(layout_interner, env.target_info);
|
||||||
|
|
||||||
|
@ -2859,7 +2863,7 @@ pub fn build_exp_stmt<'a, 'ctx>(
|
||||||
|
|
||||||
_ if lay.is_refcounted() => {
|
_ if lay.is_refcounted() => {
|
||||||
if value.is_pointer_value() {
|
if value.is_pointer_value() {
|
||||||
let value_ptr = match lay.repr {
|
let value_ptr = match lay {
|
||||||
LayoutRepr::Union(union_layout)
|
LayoutRepr::Union(union_layout)
|
||||||
if union_layout
|
if union_layout
|
||||||
.stores_tag_id_in_pointer(env.target_info) =>
|
.stores_tag_id_in_pointer(env.target_info) =>
|
||||||
|
@ -3437,7 +3441,7 @@ fn build_switch_ir<'a, 'ctx>(
|
||||||
let cont_block = context.append_basic_block(parent, "cont");
|
let cont_block = context.append_basic_block(parent, "cont");
|
||||||
|
|
||||||
// Build the condition
|
// Build the condition
|
||||||
let cond = match layout_interner.get(cond_layout).repr {
|
let cond = match layout_interner.get_repr(cond_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
||||||
// float matches are done on the bit pattern
|
// float matches are done on the bit pattern
|
||||||
cond_layout = Layout::float_width(float_width);
|
cond_layout = Layout::float_width(float_width);
|
||||||
|
@ -3463,7 +3467,7 @@ fn build_switch_ir<'a, 'ctx>(
|
||||||
// Build the cases
|
// Build the cases
|
||||||
let mut incoming = Vec::with_capacity_in(branches.len(), arena);
|
let mut incoming = Vec::with_capacity_in(branches.len(), arena);
|
||||||
|
|
||||||
if let LayoutRepr::Builtin(Builtin::Bool) = layout_interner.get(cond_layout).repr {
|
if let LayoutRepr::Builtin(Builtin::Bool) = layout_interner.get_repr(cond_layout) {
|
||||||
match (branches, default_branch) {
|
match (branches, default_branch) {
|
||||||
([(0, _, false_branch)], true_branch) | ([(1, _, true_branch)], false_branch) => {
|
([(0, _, false_branch)], true_branch) | ([(1, _, true_branch)], false_branch) => {
|
||||||
let then_block = context.append_basic_block(parent, "then_block");
|
let then_block = context.append_basic_block(parent, "then_block");
|
||||||
|
@ -3764,7 +3768,7 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>(
|
||||||
|
|
||||||
builder.position_at_end(entry);
|
builder.position_at_end(entry);
|
||||||
|
|
||||||
let wrapped_layout = layout_interner.insert_no_semantic(roc_call_result_layout(
|
let wrapped_layout = layout_interner.insert_direct_no_semantic(roc_call_result_layout(
|
||||||
env.arena,
|
env.arena,
|
||||||
return_layout,
|
return_layout,
|
||||||
env.target_info,
|
env.target_info,
|
||||||
|
@ -3871,7 +3875,7 @@ fn expose_function_to_host_help_c_abi_gen_test<'a, 'ctx>(
|
||||||
// the C and Fast calling conventions agree
|
// the C and Fast calling conventions agree
|
||||||
arguments_for_call.push(*arg);
|
arguments_for_call.push(*arg);
|
||||||
} else {
|
} else {
|
||||||
match layout_interner.get(*layout).repr {
|
match layout_interner.get_repr(*layout) {
|
||||||
LayoutRepr::Builtin(Builtin::List(_)) => {
|
LayoutRepr::Builtin(Builtin::List(_)) => {
|
||||||
let list_type = arg_type
|
let list_type = arg_type
|
||||||
.into_pointer_type()
|
.into_pointer_type()
|
||||||
|
@ -3905,7 +3909,7 @@ fn expose_function_to_host_help_c_abi_gen_test<'a, 'ctx>(
|
||||||
|
|
||||||
builder.position_at_end(last_block);
|
builder.position_at_end(last_block);
|
||||||
|
|
||||||
let wrapper_result = layout_interner.insert_no_semantic(LayoutRepr::struct_(
|
let wrapper_result = layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(
|
||||||
env.arena.alloc([Layout::U64, return_layout]),
|
env.arena.alloc([Layout::U64, return_layout]),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -4010,7 +4014,7 @@ fn expose_function_to_host_help_c_abi_v2<'a, 'ctx>(
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i, layout) in arguments.iter().enumerate() {
|
for (i, layout) in arguments.iter().enumerate() {
|
||||||
if let LayoutRepr::Builtin(Builtin::Str) = layout_interner.get(*layout).repr {
|
if let LayoutRepr::Builtin(Builtin::Str) = layout_interner.get_repr(*layout) {
|
||||||
// Indicate to LLVM that this argument is semantically passed by-value
|
// Indicate to LLVM that this argument is semantically passed by-value
|
||||||
// even though technically (because of its size) it is passed by-reference
|
// even though technically (because of its size) it is passed by-reference
|
||||||
let byval_attribute_id = Attribute::get_named_enum_kind_id("byval");
|
let byval_attribute_id = Attribute::get_named_enum_kind_id("byval");
|
||||||
|
@ -4110,7 +4114,7 @@ fn expose_function_to_host_help_c_abi_v2<'a, 'ctx>(
|
||||||
env.target_info.architecture,
|
env.target_info.architecture,
|
||||||
roc_target::Architecture::X86_32 | roc_target::Architecture::X86_64
|
roc_target::Architecture::X86_32 | roc_target::Architecture::X86_64
|
||||||
) {
|
) {
|
||||||
let c_abi_type = match layout_interner.get(*layout).repr {
|
let c_abi_type = match layout_interner.get_repr(*layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Str | Builtin::List(_)) => {
|
LayoutRepr::Builtin(Builtin::Str | Builtin::List(_)) => {
|
||||||
c_abi_roc_str_type
|
c_abi_roc_str_type
|
||||||
}
|
}
|
||||||
|
@ -5679,7 +5683,7 @@ fn to_cc_type<'a, 'ctx>(
|
||||||
layout_interner: &mut STLayoutInterner<'a>,
|
layout_interner: &mut STLayoutInterner<'a>,
|
||||||
layout: InLayout<'a>,
|
layout: InLayout<'a>,
|
||||||
) -> BasicTypeEnum<'ctx> {
|
) -> BasicTypeEnum<'ctx> {
|
||||||
match layout_interner.runtime_representation(layout).repr {
|
match layout_interner.runtime_representation(layout) {
|
||||||
LayoutRepr::Builtin(builtin) => to_cc_type_builtin(env, &builtin),
|
LayoutRepr::Builtin(builtin) => to_cc_type_builtin(env, &builtin),
|
||||||
_ => {
|
_ => {
|
||||||
// TODO this is almost certainly incorrect for bigger structs
|
// TODO this is almost certainly incorrect for bigger structs
|
||||||
|
@ -5726,7 +5730,7 @@ impl RocReturn {
|
||||||
target_info: TargetInfo,
|
target_info: TargetInfo,
|
||||||
layout: InLayout,
|
layout: InLayout,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match interner.get(layout).repr {
|
match interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(builtin) => {
|
LayoutRepr::Builtin(builtin) => {
|
||||||
use Builtin::*;
|
use Builtin::*;
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ fn build_eq<'a, 'ctx>(
|
||||||
rhs_layout
|
rhs_layout
|
||||||
);
|
);
|
||||||
|
|
||||||
match layout_interner.get(*lhs_layout).repr {
|
match layout_interner.get_repr(*lhs_layout) {
|
||||||
LayoutRepr::Builtin(builtin) => build_eq_builtin(
|
LayoutRepr::Builtin(builtin) => build_eq_builtin(
|
||||||
env,
|
env,
|
||||||
layout_interner,
|
layout_interner,
|
||||||
|
@ -215,7 +215,7 @@ fn build_eq<'a, 'ctx>(
|
||||||
"i64_to_opaque",
|
"i64_to_opaque",
|
||||||
);
|
);
|
||||||
|
|
||||||
let union_layout = match layout_interner.get(rec_layout).repr {
|
let union_layout = match layout_interner.get_repr(rec_layout) {
|
||||||
LayoutRepr::Union(union_layout) => {
|
LayoutRepr::Union(union_layout) => {
|
||||||
debug_assert!(!matches!(union_layout, UnionLayout::NonRecursive(..)));
|
debug_assert!(!matches!(union_layout, UnionLayout::NonRecursive(..)));
|
||||||
union_layout
|
union_layout
|
||||||
|
@ -342,7 +342,7 @@ fn build_neq<'a, 'ctx>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
match layout_interner.get(lhs_layout).repr {
|
match layout_interner.get_repr(lhs_layout) {
|
||||||
LayoutRepr::Builtin(builtin) => build_neq_builtin(
|
LayoutRepr::Builtin(builtin) => build_neq_builtin(
|
||||||
env,
|
env,
|
||||||
layout_interner,
|
layout_interner,
|
||||||
|
@ -425,7 +425,7 @@ fn build_list_eq<'a, 'ctx>(
|
||||||
|
|
||||||
let symbol = Symbol::LIST_EQ;
|
let symbol = Symbol::LIST_EQ;
|
||||||
let element_layout =
|
let element_layout =
|
||||||
if let LayoutRepr::RecursivePointer(rec) = layout_interner.get(element_layout).repr {
|
if let LayoutRepr::RecursivePointer(rec) = layout_interner.get_repr(element_layout) {
|
||||||
rec
|
rec
|
||||||
} else {
|
} else {
|
||||||
element_layout
|
element_layout
|
||||||
|
@ -742,10 +742,10 @@ fn build_struct_eq_help<'a, 'ctx>(
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let are_equal = if let LayoutRepr::RecursivePointer(rec_layout) =
|
let are_equal = if let LayoutRepr::RecursivePointer(rec_layout) =
|
||||||
layout_interner.get(*field_layout).repr
|
layout_interner.get_repr(*field_layout)
|
||||||
{
|
{
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
matches!(layout_interner.get(rec_layout).repr, LayoutRepr::Union(union_layout) if !matches!(union_layout, UnionLayout::NonRecursive(..)))
|
matches!(layout_interner.get_repr(rec_layout), LayoutRepr::Union(union_layout) if !matches!(union_layout, UnionLayout::NonRecursive(..)))
|
||||||
);
|
);
|
||||||
|
|
||||||
let field_layout = rec_layout;
|
let field_layout = rec_layout;
|
||||||
|
@ -973,7 +973,7 @@ fn build_tag_eq_help<'a, 'ctx>(
|
||||||
env.builder.position_at_end(block);
|
env.builder.position_at_end(block);
|
||||||
|
|
||||||
let struct_layout =
|
let struct_layout =
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||||
|
|
||||||
let answer = eq_ptr_to_struct(
|
let answer = eq_ptr_to_struct(
|
||||||
env,
|
env,
|
||||||
|
@ -1046,7 +1046,7 @@ fn build_tag_eq_help<'a, 'ctx>(
|
||||||
env.builder.position_at_end(block);
|
env.builder.position_at_end(block);
|
||||||
|
|
||||||
let struct_layout =
|
let struct_layout =
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||||
|
|
||||||
let answer = eq_ptr_to_struct(
|
let answer = eq_ptr_to_struct(
|
||||||
env,
|
env,
|
||||||
|
@ -1109,7 +1109,7 @@ fn build_tag_eq_help<'a, 'ctx>(
|
||||||
env.builder.position_at_end(compare_other);
|
env.builder.position_at_end(compare_other);
|
||||||
|
|
||||||
let struct_layout =
|
let struct_layout =
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(other_fields));
|
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(other_fields));
|
||||||
|
|
||||||
let answer = eq_ptr_to_struct(
|
let answer = eq_ptr_to_struct(
|
||||||
env,
|
env,
|
||||||
|
@ -1214,7 +1214,7 @@ fn build_tag_eq_help<'a, 'ctx>(
|
||||||
env.builder.position_at_end(block);
|
env.builder.position_at_end(block);
|
||||||
|
|
||||||
let struct_layout =
|
let struct_layout =
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||||
|
|
||||||
let answer = eq_ptr_to_struct(
|
let answer = eq_ptr_to_struct(
|
||||||
env,
|
env,
|
||||||
|
@ -1255,7 +1255,7 @@ fn build_tag_eq_help<'a, 'ctx>(
|
||||||
env.builder.position_at_end(compare_fields);
|
env.builder.position_at_end(compare_fields);
|
||||||
|
|
||||||
let struct_layout =
|
let struct_layout =
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||||
|
|
||||||
let answer = eq_ptr_to_struct(
|
let answer = eq_ptr_to_struct(
|
||||||
env,
|
env,
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>(
|
||||||
) -> BasicTypeEnum<'ctx> {
|
) -> BasicTypeEnum<'ctx> {
|
||||||
use LayoutRepr::*;
|
use LayoutRepr::*;
|
||||||
|
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get_repr(layout) {
|
||||||
Struct(sorted_fields, ..) => basic_type_from_record(env, layout_interner, sorted_fields),
|
Struct(sorted_fields, ..) => basic_type_from_record(env, layout_interner, sorted_fields),
|
||||||
LambdaSet(lambda_set) => {
|
LambdaSet(lambda_set) => {
|
||||||
basic_type_from_layout(env, layout_interner, lambda_set.runtime_representation())
|
basic_type_from_layout(env, layout_interner, lambda_set.runtime_representation())
|
||||||
|
@ -150,7 +150,7 @@ pub fn argument_type_from_layout<'a, 'ctx>(
|
||||||
) -> BasicTypeEnum<'ctx> {
|
) -> BasicTypeEnum<'ctx> {
|
||||||
use LayoutRepr::*;
|
use LayoutRepr::*;
|
||||||
|
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get_repr(layout) {
|
||||||
LambdaSet(lambda_set) => {
|
LambdaSet(lambda_set) => {
|
||||||
argument_type_from_layout(env, layout_interner, lambda_set.runtime_representation())
|
argument_type_from_layout(env, layout_interner, lambda_set.runtime_representation())
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,7 +296,7 @@ fn build_clone<'a, 'ctx>(
|
||||||
value: BasicValueEnum<'ctx>,
|
value: BasicValueEnum<'ctx>,
|
||||||
layout: InLayout<'a>,
|
layout: InLayout<'a>,
|
||||||
) -> IntValue<'ctx> {
|
) -> IntValue<'ctx> {
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(builtin) => build_clone_builtin(
|
LayoutRepr::Builtin(builtin) => build_clone_builtin(
|
||||||
env,
|
env,
|
||||||
layout_interner,
|
layout_interner,
|
||||||
|
@ -396,7 +396,7 @@ fn build_clone<'a, 'ctx>(
|
||||||
"i64_to_opaque",
|
"i64_to_opaque",
|
||||||
);
|
);
|
||||||
|
|
||||||
let union_layout = match layout_interner.get(rec_layout).repr {
|
let union_layout = match layout_interner.get_repr(rec_layout) {
|
||||||
LayoutRepr::Union(union_layout) => {
|
LayoutRepr::Union(union_layout) => {
|
||||||
debug_assert!(!matches!(union_layout, UnionLayout::NonRecursive(..)));
|
debug_assert!(!matches!(union_layout, UnionLayout::NonRecursive(..)));
|
||||||
union_layout
|
union_layout
|
||||||
|
@ -476,7 +476,7 @@ fn build_clone_tag<'a, 'ctx>(
|
||||||
value: BasicValueEnum<'ctx>,
|
value: BasicValueEnum<'ctx>,
|
||||||
union_layout: UnionLayout<'a>,
|
union_layout: UnionLayout<'a>,
|
||||||
) -> IntValue<'ctx> {
|
) -> IntValue<'ctx> {
|
||||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
let layout_id = layout_ids.get(Symbol::CLONE, &layout);
|
let layout_id = layout_ids.get(Symbol::CLONE, &layout);
|
||||||
let fn_name = layout_id.to_symbol_string(Symbol::CLONE, &env.interns);
|
let fn_name = layout_id.to_symbol_string(Symbol::CLONE, &env.interns);
|
||||||
|
|
||||||
|
@ -690,7 +690,7 @@ fn build_clone_tag_help<'a, 'ctx>(
|
||||||
|
|
||||||
// load the tag payload (if any)
|
// load the tag payload (if any)
|
||||||
let payload_layout = LayoutRepr::struct_(field_layouts);
|
let payload_layout = LayoutRepr::struct_(field_layouts);
|
||||||
let payload_in_layout = layout_interner.insert_no_semantic(payload_layout);
|
let payload_in_layout = layout_interner.insert_direct_no_semantic(payload_layout);
|
||||||
|
|
||||||
let opaque_payload_ptr = env
|
let opaque_payload_ptr = env
|
||||||
.builder
|
.builder
|
||||||
|
@ -748,11 +748,12 @@ fn build_clone_tag_help<'a, 'ctx>(
|
||||||
|
|
||||||
let tag_value = tag_pointer_clear_tag_id(env, tag_value.into_pointer_value());
|
let tag_value = tag_pointer_clear_tag_id(env, tag_value.into_pointer_value());
|
||||||
|
|
||||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
let layout =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||||
let layout = if union_layout.stores_tag_id_in_pointer(env.target_info) {
|
let layout = if union_layout.stores_tag_id_in_pointer(env.target_info) {
|
||||||
layout
|
layout
|
||||||
} else {
|
} else {
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(
|
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(
|
||||||
env.arena.alloc([layout, union_layout.tag_id_layout()]),
|
env.arena.alloc([layout, union_layout.tag_id_layout()]),
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
@ -797,7 +798,7 @@ fn build_clone_tag_help<'a, 'ctx>(
|
||||||
|
|
||||||
build_copy(env, ptr, offset, extra_offset.into());
|
build_copy(env, ptr, offset, extra_offset.into());
|
||||||
|
|
||||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::struct_(fields));
|
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(fields));
|
||||||
let basic_type = basic_type_from_layout(env, layout_interner, layout);
|
let basic_type = basic_type_from_layout(env, layout_interner, layout);
|
||||||
|
|
||||||
let (width, _) = union_layout.data_size_and_alignment(layout_interner, env.target_info);
|
let (width, _) = union_layout.data_size_and_alignment(layout_interner, env.target_info);
|
||||||
|
@ -853,7 +854,8 @@ fn build_clone_tag_help<'a, 'ctx>(
|
||||||
other_tags[i]
|
other_tags[i]
|
||||||
};
|
};
|
||||||
|
|
||||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::struct_(fields));
|
let layout =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(fields));
|
||||||
let basic_type = basic_type_from_layout(env, layout_interner, layout);
|
let basic_type = basic_type_from_layout(env, layout_interner, layout);
|
||||||
|
|
||||||
let (width, _) =
|
let (width, _) =
|
||||||
|
@ -928,7 +930,8 @@ fn build_clone_tag_help<'a, 'ctx>(
|
||||||
// write the "pointer" af the current offset
|
// write the "pointer" af the current offset
|
||||||
build_copy(env, ptr, offset, extra_offset.into());
|
build_copy(env, ptr, offset, extra_offset.into());
|
||||||
|
|
||||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::struct_(other_fields));
|
let layout =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(other_fields));
|
||||||
let basic_type = basic_type_from_layout(env, layout_interner, layout);
|
let basic_type = basic_type_from_layout(env, layout_interner, layout);
|
||||||
|
|
||||||
let cursors = Cursors {
|
let cursors = Cursors {
|
||||||
|
|
|
@ -200,13 +200,13 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
// Str.toNum : Str -> Result (Num *) {}
|
// Str.toNum : Str -> Result (Num *) {}
|
||||||
arguments!(string);
|
arguments!(string);
|
||||||
|
|
||||||
let number_layout = match layout_interner.get(layout).repr {
|
let number_layout = match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Struct(field_layouts) => field_layouts[0], // TODO: why is it sometimes a struct?
|
LayoutRepr::Struct(field_layouts) => field_layouts[0], // TODO: why is it sometimes a struct?
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// match on the return layout to figure out which zig builtin we need
|
// match on the return layout to figure out which zig builtin we need
|
||||||
let intrinsic = match layout_interner.get(number_layout).repr {
|
let intrinsic = match layout_interner.get_repr(number_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => &bitcode::STR_TO_INT[int_width],
|
LayoutRepr::Builtin(Builtin::Int(int_width)) => &bitcode::STR_TO_INT[int_width],
|
||||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
||||||
&bitcode::STR_TO_FLOAT[float_width]
|
&bitcode::STR_TO_FLOAT[float_width]
|
||||||
|
@ -229,7 +229,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
intrinsic,
|
intrinsic,
|
||||||
),
|
),
|
||||||
None => {
|
None => {
|
||||||
let return_type_name = match layout_interner.get(number_layout).repr {
|
let return_type_name = match layout_interner.get_repr(number_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
|
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
|
||||||
int_width.type_name()
|
int_width.type_name()
|
||||||
}
|
}
|
||||||
|
@ -279,7 +279,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PtrWidth::Bytes8 => {
|
PtrWidth::Bytes8 => {
|
||||||
let cc_return_by_pointer = match layout_interner.get(number_layout).repr {
|
let cc_return_by_pointer = match layout_interner.get_repr(number_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
|
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
|
||||||
(int_width.stack_size() as usize > env.target_info.ptr_size())
|
(int_width.stack_size() as usize > env.target_info.ptr_size())
|
||||||
.then_some(int_width.type_name())
|
.then_some(int_width.type_name())
|
||||||
|
@ -325,7 +325,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
let (int, int_layout) = load_symbol_and_layout(scope, &args[0]);
|
let (int, int_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||||
let int = int.into_int_value();
|
let int = int.into_int_value();
|
||||||
|
|
||||||
let int_width = match layout_interner.get(int_layout).repr {
|
let int_width = match layout_interner.get_repr(int_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
|
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
@ -344,7 +344,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
|
|
||||||
let (float, float_layout) = load_symbol_and_layout(scope, &args[0]);
|
let (float, float_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||||
|
|
||||||
let float_width = match layout_interner.get(float_layout).repr {
|
let float_width = match layout_interner.get_repr(float_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => float_width,
|
LayoutRepr::Builtin(Builtin::Float(float_width)) => float_width,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
@ -854,7 +854,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
// Num.toStr : Num a -> Str
|
// Num.toStr : Num a -> Str
|
||||||
arguments_with_layouts!((num, num_layout));
|
arguments_with_layouts!((num, num_layout));
|
||||||
|
|
||||||
match layout_interner.get(num_layout).repr {
|
match layout_interner.get_repr(num_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
|
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
|
||||||
let int = num.into_int_value();
|
let int = num.into_int_value();
|
||||||
|
|
||||||
|
@ -869,7 +869,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
LayoutRepr::Builtin(Builtin::Float(_float_width)) => {
|
LayoutRepr::Builtin(Builtin::Float(_float_width)) => {
|
||||||
let (float, float_layout) = load_symbol_and_layout(scope, &args[0]);
|
let (float, float_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||||
|
|
||||||
let float_width = match layout_interner.get(float_layout).repr {
|
let float_width = match layout_interner.get_repr(float_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => float_width,
|
LayoutRepr::Builtin(Builtin::Float(float_width)) => float_width,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
@ -908,7 +908,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
| NumCountOneBits => {
|
| NumCountOneBits => {
|
||||||
arguments_with_layouts!((arg, arg_layout));
|
arguments_with_layouts!((arg, arg_layout));
|
||||||
|
|
||||||
match layout_interner.get(arg_layout).repr {
|
match layout_interner.get_repr(arg_layout) {
|
||||||
LayoutRepr::Builtin(arg_builtin) => {
|
LayoutRepr::Builtin(arg_builtin) => {
|
||||||
use roc_mono::layout::Builtin::*;
|
use roc_mono::layout::Builtin::*;
|
||||||
|
|
||||||
|
@ -996,8 +996,8 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
|
|
||||||
use inkwell::FloatPredicate;
|
use inkwell::FloatPredicate;
|
||||||
match (
|
match (
|
||||||
layout_interner.get(lhs_layout).repr,
|
layout_interner.get_repr(lhs_layout),
|
||||||
layout_interner.get(rhs_layout).repr,
|
layout_interner.get_repr(rhs_layout),
|
||||||
) {
|
) {
|
||||||
(LayoutRepr::Builtin(lhs_builtin), LayoutRepr::Builtin(rhs_builtin))
|
(LayoutRepr::Builtin(lhs_builtin), LayoutRepr::Builtin(rhs_builtin))
|
||||||
if lhs_builtin == rhs_builtin =>
|
if lhs_builtin == rhs_builtin =>
|
||||||
|
@ -1152,7 +1152,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
NumToFloatCast => {
|
NumToFloatCast => {
|
||||||
arguments_with_layouts!((arg, arg_layout));
|
arguments_with_layouts!((arg, arg_layout));
|
||||||
|
|
||||||
match layout_interner.get(arg_layout).repr {
|
match layout_interner.get_repr(arg_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
// Converting from int to float
|
// Converting from int to float
|
||||||
let int_val = arg.into_int_value();
|
let int_val = arg.into_int_value();
|
||||||
|
@ -1291,7 +1291,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
"cast_to_i8_ptr",
|
"cast_to_i8_ptr",
|
||||||
);
|
);
|
||||||
|
|
||||||
let value_ptr = match layout_interner.get(data_layout).repr {
|
let value_ptr = match layout_interner.get_repr(data_layout) {
|
||||||
LayoutRepr::Union(union_layout)
|
LayoutRepr::Union(union_layout)
|
||||||
if union_layout.stores_tag_id_in_pointer(env.target_info) =>
|
if union_layout.stores_tag_id_in_pointer(env.target_info) =>
|
||||||
{
|
{
|
||||||
|
@ -1562,8 +1562,8 @@ pub fn build_num_binop<'a, 'ctx>(
|
||||||
op: LowLevel,
|
op: LowLevel,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
match (
|
match (
|
||||||
layout_interner.get(lhs_layout).repr,
|
layout_interner.get_repr(lhs_layout),
|
||||||
layout_interner.get(rhs_layout).repr,
|
layout_interner.get_repr(rhs_layout),
|
||||||
) {
|
) {
|
||||||
(LayoutRepr::Builtin(lhs_builtin), LayoutRepr::Builtin(rhs_builtin))
|
(LayoutRepr::Builtin(lhs_builtin), LayoutRepr::Builtin(rhs_builtin))
|
||||||
if lhs_builtin == rhs_builtin =>
|
if lhs_builtin == rhs_builtin =>
|
||||||
|
@ -2031,7 +2031,7 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
||||||
NumToFrac => {
|
NumToFrac => {
|
||||||
// This is an Int, so we need to convert it.
|
// This is an Int, so we need to convert it.
|
||||||
|
|
||||||
let target_float_type = match layout_interner.get(return_layout).repr {
|
let target_float_type = match layout_interner.get_repr(return_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
||||||
convert::float_type_from_float_width(env, float_width)
|
convert::float_type_from_float_width(env, float_width)
|
||||||
}
|
}
|
||||||
|
@ -2048,7 +2048,7 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
||||||
NumToIntChecked => {
|
NumToIntChecked => {
|
||||||
// return_layout : Result N [OutOfBounds]* ~ { result: N, out_of_bounds: bool }
|
// return_layout : Result N [OutOfBounds]* ~ { result: N, out_of_bounds: bool }
|
||||||
|
|
||||||
let target_int_width = match layout_interner.get(return_layout).repr {
|
let target_int_width = match layout_interner.get_repr(return_layout) {
|
||||||
LayoutRepr::Struct(field_layouts) if field_layouts.len() == 2 => {
|
LayoutRepr::Struct(field_layouts) if field_layouts.len() == 2 => {
|
||||||
debug_assert!(layout_interner.eq_repr(field_layouts[1], Layout::BOOL));
|
debug_assert!(layout_interner.eq_repr(field_layouts[1], Layout::BOOL));
|
||||||
field_layouts[0].to_int_width()
|
field_layouts[0].to_int_width()
|
||||||
|
@ -2328,7 +2328,7 @@ fn build_float_unary_op<'a, 'ctx>(
|
||||||
NumSqrtUnchecked => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_SQRT[float_width]),
|
NumSqrtUnchecked => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_SQRT[float_width]),
|
||||||
NumLogUnchecked => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_LOG[float_width]),
|
NumLogUnchecked => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_LOG[float_width]),
|
||||||
NumToFrac => {
|
NumToFrac => {
|
||||||
let return_width = match layout_interner.get(layout).repr {
|
let return_width = match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Float(return_width)) => return_width,
|
LayoutRepr::Builtin(Builtin::Float(return_width)) => return_width,
|
||||||
_ => internal_error!("Layout for returning is not Float : {:?}", layout),
|
_ => internal_error!("Layout for returning is not Float : {:?}", layout),
|
||||||
};
|
};
|
||||||
|
@ -2350,7 +2350,7 @@ fn build_float_unary_op<'a, 'ctx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NumCeiling => {
|
NumCeiling => {
|
||||||
let int_width = match layout_interner.get(layout).repr {
|
let int_width = match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
|
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
|
||||||
_ => internal_error!("Ceiling return layout is not int: {:?}", layout),
|
_ => internal_error!("Ceiling return layout is not int: {:?}", layout),
|
||||||
};
|
};
|
||||||
|
@ -2364,7 +2364,7 @@ fn build_float_unary_op<'a, 'ctx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NumFloor => {
|
NumFloor => {
|
||||||
let int_width = match layout_interner.get(layout).repr {
|
let int_width = match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
|
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
|
||||||
_ => internal_error!("Floor return layout is not int: {:?}", layout),
|
_ => internal_error!("Floor return layout is not int: {:?}", layout),
|
||||||
};
|
};
|
||||||
|
@ -2378,7 +2378,7 @@ fn build_float_unary_op<'a, 'ctx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NumRound => {
|
NumRound => {
|
||||||
let int_width = match layout_interner.get(layout).repr {
|
let int_width = match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
|
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
|
||||||
_ => internal_error!("Round return layout is not int: {:?}", layout),
|
_ => internal_error!("Round return layout is not int: {:?}", layout),
|
||||||
};
|
};
|
||||||
|
@ -2465,8 +2465,8 @@ pub(crate) fn run_higher_order_low_level<'a, 'ctx>(
|
||||||
let (function, closure, closure_layout) = function_details!();
|
let (function, closure, closure_layout) = function_details!();
|
||||||
|
|
||||||
match (
|
match (
|
||||||
layout_interner.get(list_layout).repr,
|
layout_interner.get_repr(list_layout),
|
||||||
layout_interner.get(return_layout).repr,
|
layout_interner.get_repr(return_layout),
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
LayoutRepr::Builtin(Builtin::List(element_layout)),
|
LayoutRepr::Builtin(Builtin::List(element_layout)),
|
||||||
|
@ -2505,9 +2505,9 @@ pub(crate) fn run_higher_order_low_level<'a, 'ctx>(
|
||||||
let (function, closure, closure_layout) = function_details!();
|
let (function, closure, closure_layout) = function_details!();
|
||||||
|
|
||||||
match (
|
match (
|
||||||
layout_interner.get(list1_layout).repr,
|
layout_interner.get_repr(list1_layout),
|
||||||
layout_interner.get(list2_layout).repr,
|
layout_interner.get_repr(list2_layout),
|
||||||
layout_interner.get(return_layout).repr,
|
layout_interner.get_repr(return_layout),
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
LayoutRepr::Builtin(Builtin::List(element1_layout)),
|
LayoutRepr::Builtin(Builtin::List(element1_layout)),
|
||||||
|
@ -2551,10 +2551,10 @@ pub(crate) fn run_higher_order_low_level<'a, 'ctx>(
|
||||||
let (function, closure, closure_layout) = function_details!();
|
let (function, closure, closure_layout) = function_details!();
|
||||||
|
|
||||||
match (
|
match (
|
||||||
layout_interner.get(list1_layout).repr,
|
layout_interner.get_repr(list1_layout),
|
||||||
layout_interner.get(list2_layout).repr,
|
layout_interner.get_repr(list2_layout),
|
||||||
layout_interner.get(list3_layout).repr,
|
layout_interner.get_repr(list3_layout),
|
||||||
layout_interner.get(return_layout).repr,
|
layout_interner.get_repr(return_layout),
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
LayoutRepr::Builtin(Builtin::List(element1_layout)),
|
LayoutRepr::Builtin(Builtin::List(element1_layout)),
|
||||||
|
@ -2602,11 +2602,11 @@ pub(crate) fn run_higher_order_low_level<'a, 'ctx>(
|
||||||
let (function, closure, closure_layout) = function_details!();
|
let (function, closure, closure_layout) = function_details!();
|
||||||
|
|
||||||
match (
|
match (
|
||||||
layout_interner.get(list1_layout).repr,
|
layout_interner.get_repr(list1_layout),
|
||||||
layout_interner.get(list2_layout).repr,
|
layout_interner.get_repr(list2_layout),
|
||||||
layout_interner.get(list3_layout).repr,
|
layout_interner.get_repr(list3_layout),
|
||||||
layout_interner.get(list4_layout).repr,
|
layout_interner.get_repr(list4_layout),
|
||||||
layout_interner.get(return_layout).repr,
|
layout_interner.get_repr(return_layout),
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
LayoutRepr::Builtin(Builtin::List(element1_layout)),
|
LayoutRepr::Builtin(Builtin::List(element1_layout)),
|
||||||
|
@ -2659,7 +2659,7 @@ pub(crate) fn run_higher_order_low_level<'a, 'ctx>(
|
||||||
|
|
||||||
let (function, closure, closure_layout) = function_details!();
|
let (function, closure, closure_layout) = function_details!();
|
||||||
|
|
||||||
match layout_interner.get(list_layout).repr {
|
match layout_interner.get_repr(list_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
|
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
|
||||||
use crate::llvm::bitcode::build_compare_wrapper;
|
use crate::llvm::bitcode::build_compare_wrapper;
|
||||||
|
|
||||||
|
@ -2710,7 +2710,7 @@ fn load_symbol_and_lambda_set<'a, 'ctx>(
|
||||||
) -> (BasicValueEnum<'ctx>, LambdaSet<'a>) {
|
) -> (BasicValueEnum<'ctx>, LambdaSet<'a>) {
|
||||||
match scope
|
match scope
|
||||||
.get(symbol)
|
.get(symbol)
|
||||||
.map(|(l, v)| (layout_interner.get(*l).repr, v))
|
.map(|(l, v)| (layout_interner.get_repr(*l), v))
|
||||||
{
|
{
|
||||||
Some((LayoutRepr::LambdaSet(lambda_set), ptr)) => (*ptr, lambda_set),
|
Some((LayoutRepr::LambdaSet(lambda_set), ptr)) => (*ptr, lambda_set),
|
||||||
Some((other, ptr)) => panic!("Not a lambda set: {:?}, {:?}", other, ptr),
|
Some((other, ptr)) => panic!("Not a lambda set: {:?}, {:?}", other, ptr),
|
||||||
|
|
|
@ -267,7 +267,7 @@ fn modify_refcount_struct<'a, 'ctx>(
|
||||||
let block = env.builder.get_insert_block().expect("to be in a function");
|
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||||
|
|
||||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::struct_(layouts));
|
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(layouts));
|
||||||
|
|
||||||
let (_, fn_name) = function_name_from_mode(
|
let (_, fn_name) = function_name_from_mode(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
|
@ -470,7 +470,7 @@ fn modify_refcount_layout_help<'a, 'ctx>(
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::RecursivePointer(rec_layout) => {
|
LayoutRepr::RecursivePointer(rec_layout) => {
|
||||||
let layout = rec_layout;
|
let layout = rec_layout;
|
||||||
|
|
||||||
|
@ -527,7 +527,7 @@ fn modify_refcount_layout_build_function<'a, 'ctx>(
|
||||||
) -> Option<FunctionValue<'ctx>> {
|
) -> Option<FunctionValue<'ctx>> {
|
||||||
use LayoutRepr::*;
|
use LayoutRepr::*;
|
||||||
|
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get_repr(layout) {
|
||||||
Builtin(builtin) => {
|
Builtin(builtin) => {
|
||||||
modify_refcount_builtin(env, layout_interner, layout_ids, mode, layout, &builtin)
|
modify_refcount_builtin(env, layout_interner, layout_ids, mode, layout, &builtin)
|
||||||
}
|
}
|
||||||
|
@ -603,14 +603,14 @@ fn modify_refcount_list<'a, 'ctx>(
|
||||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||||
|
|
||||||
let element_layout =
|
let element_layout =
|
||||||
if let LayoutRepr::RecursivePointer(rec) = layout_interner.get(element_layout).repr {
|
if let LayoutRepr::RecursivePointer(rec) = layout_interner.get_repr(element_layout) {
|
||||||
rec
|
rec
|
||||||
} else {
|
} else {
|
||||||
element_layout
|
element_layout
|
||||||
};
|
};
|
||||||
|
|
||||||
let list_layout =
|
let list_layout = layout_interner
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(element_layout)));
|
.insert_direct_no_semantic(LayoutRepr::Builtin(Builtin::List(element_layout)));
|
||||||
let (_, fn_name) = function_name_from_mode(
|
let (_, fn_name) = function_name_from_mode(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
&env.interns,
|
&env.interns,
|
||||||
|
@ -859,7 +859,7 @@ fn modify_refcount_boxed<'a, 'ctx>(
|
||||||
let block = env.builder.get_insert_block().expect("to be in a function");
|
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||||
|
|
||||||
let boxed_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(inner_layout));
|
let boxed_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(inner_layout));
|
||||||
|
|
||||||
let (_, fn_name) = function_name_from_mode(
|
let (_, fn_name) = function_name_from_mode(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
|
@ -921,7 +921,7 @@ fn modify_refcount_box_help<'a, 'ctx>(
|
||||||
let boxed = arg_val.into_pointer_value();
|
let boxed = arg_val.into_pointer_value();
|
||||||
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, boxed);
|
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, boxed);
|
||||||
let call_mode = mode_to_call_mode(fn_val, mode);
|
let call_mode = mode_to_call_mode(fn_val, mode);
|
||||||
let boxed_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(inner_layout));
|
let boxed_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(inner_layout));
|
||||||
|
|
||||||
match mode {
|
match mode {
|
||||||
Mode::Inc => {
|
Mode::Inc => {
|
||||||
|
@ -1065,7 +1065,7 @@ fn build_rec_union<'a, 'ctx>(
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
union_layout: UnionLayout<'a>,
|
union_layout: UnionLayout<'a>,
|
||||||
) -> FunctionValue<'ctx> {
|
) -> FunctionValue<'ctx> {
|
||||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
|
|
||||||
let (_, fn_name) = function_name_from_mode(
|
let (_, fn_name) = function_name_from_mode(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
|
@ -1168,7 +1168,7 @@ fn build_rec_union_help<'a, 'ctx>(
|
||||||
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, value_ptr);
|
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, value_ptr);
|
||||||
let call_mode = mode_to_call_mode(fn_val, mode);
|
let call_mode = mode_to_call_mode(fn_val, mode);
|
||||||
|
|
||||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
|
|
||||||
match mode {
|
match mode {
|
||||||
Mode::Inc => {
|
Mode::Inc => {
|
||||||
|
@ -1223,7 +1223,7 @@ enum DecOrReuse {
|
||||||
|
|
||||||
fn fields_need_no_refcounting(interner: &STLayoutInterner, field_layouts: &[InLayout]) -> bool {
|
fn fields_need_no_refcounting(interner: &STLayoutInterner, field_layouts: &[InLayout]) -> bool {
|
||||||
!field_layouts.iter().any(|x| {
|
!field_layouts.iter().any(|x| {
|
||||||
let x = interner.get(*x);
|
let x = interner.get_repr(*x);
|
||||||
x.is_refcounted() || x.contains_refcounted(interner)
|
x.is_refcounted() || x.contains_refcounted(interner)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1274,7 +1274,8 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
||||||
|
|
||||||
env.builder.position_at_end(block);
|
env.builder.position_at_end(block);
|
||||||
|
|
||||||
let fields_struct = layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
let fields_struct =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||||
let wrapper_type = basic_type_from_layout(env, layout_interner, fields_struct);
|
let wrapper_type = basic_type_from_layout(env, layout_interner, fields_struct);
|
||||||
|
|
||||||
// cast the opaque pointer to a pointer of the correct shape
|
// cast the opaque pointer to a pointer of the correct shape
|
||||||
|
@ -1290,7 +1291,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
||||||
let mut deferred_nonrec = Vec::new_in(env.arena);
|
let mut deferred_nonrec = Vec::new_in(env.arena);
|
||||||
|
|
||||||
for (i, field_layout) in field_layouts.iter().enumerate() {
|
for (i, field_layout) in field_layouts.iter().enumerate() {
|
||||||
if let LayoutRepr::RecursivePointer(_) = layout_interner.get(*field_layout).repr {
|
if let LayoutRepr::RecursivePointer(_) = layout_interner.get_repr(*field_layout) {
|
||||||
// this field has type `*i64`, but is really a pointer to the data we want
|
// this field has type `*i64`, but is really a pointer to the data we want
|
||||||
let elem_pointer = env
|
let elem_pointer = env
|
||||||
.builder
|
.builder
|
||||||
|
@ -1312,7 +1313,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
||||||
|
|
||||||
// therefore we must cast it to our desired type
|
// therefore we must cast it to our desired type
|
||||||
let union_layout =
|
let union_layout =
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
let union_type = basic_type_from_layout(env, layout_interner, 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);
|
let recursive_field_ptr = cast_basic_basic(env.builder, ptr_as_i64_ptr, union_type);
|
||||||
|
|
||||||
|
@ -1351,7 +1352,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
||||||
DecOrReuse::Reuse => {}
|
DecOrReuse::Reuse => {}
|
||||||
DecOrReuse::Dec => {
|
DecOrReuse::Dec => {
|
||||||
let union_layout =
|
let union_layout =
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
refcount_ptr.modify(call_mode, union_layout, env, layout_interner);
|
refcount_ptr.modify(call_mode, union_layout, env, layout_interner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1410,7 +1411,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
||||||
// increment/decrement the cons-cell itself
|
// increment/decrement the cons-cell itself
|
||||||
if let DecOrReuse::Dec = decrement_or_reuse {
|
if let DecOrReuse::Dec = decrement_or_reuse {
|
||||||
let union_layout =
|
let union_layout =
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
refcount_ptr.modify(call_mode, union_layout, env, layout_interner);
|
refcount_ptr.modify(call_mode, union_layout, env, layout_interner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1470,7 +1471,8 @@ pub fn build_reset<'a, 'ctx>(
|
||||||
) -> FunctionValue<'ctx> {
|
) -> FunctionValue<'ctx> {
|
||||||
let mode = Mode::Dec;
|
let mode = Mode::Dec;
|
||||||
|
|
||||||
let union_layout_in = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
let union_layout_in =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
let layout_id = layout_ids.get(Symbol::DEC, &union_layout_in);
|
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 = layout_id.to_symbol_string(Symbol::DEC, &env.interns);
|
||||||
let fn_name = format!("{}_reset", fn_name);
|
let fn_name = format!("{}_reset", fn_name);
|
||||||
|
@ -1566,7 +1568,7 @@ fn build_reuse_rec_union_help<'a, 'ctx>(
|
||||||
|
|
||||||
env.builder.position_at_end(should_recurse_block);
|
env.builder.position_at_end(should_recurse_block);
|
||||||
|
|
||||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
|
|
||||||
let do_recurse_block = env.context.append_basic_block(parent, "do_recurse");
|
let do_recurse_block = env.context.append_basic_block(parent, "do_recurse");
|
||||||
let no_recurse_block = env.context.append_basic_block(parent, "no_recurse");
|
let no_recurse_block = env.context.append_basic_block(parent, "no_recurse");
|
||||||
|
@ -1628,7 +1630,7 @@ fn modify_refcount_nonrecursive<'a, 'ctx>(
|
||||||
fields: &'a [&'a [InLayout<'a>]],
|
fields: &'a [&'a [InLayout<'a>]],
|
||||||
) -> FunctionValue<'ctx> {
|
) -> FunctionValue<'ctx> {
|
||||||
let union_layout = UnionLayout::NonRecursive(fields);
|
let union_layout = UnionLayout::NonRecursive(fields);
|
||||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
|
|
||||||
let block = env.builder.get_insert_block().expect("to be in a function");
|
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||||
|
@ -1698,7 +1700,7 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
|
||||||
let before_block = env.builder.get_insert_block().expect("to be in a function");
|
let before_block = env.builder.get_insert_block().expect("to be in a function");
|
||||||
|
|
||||||
let union_layout = UnionLayout::NonRecursive(tags);
|
let union_layout = UnionLayout::NonRecursive(tags);
|
||||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
let union_struct_type = basic_type_from_layout(env, layout_interner, layout).into_struct_type();
|
let union_struct_type = basic_type_from_layout(env, layout_interner, layout).into_struct_type();
|
||||||
|
|
||||||
// read the tag_id
|
// read the tag_id
|
||||||
|
@ -1735,7 +1737,7 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
|
||||||
for (tag_id, field_layouts) in tags.iter().enumerate() {
|
for (tag_id, field_layouts) in tags.iter().enumerate() {
|
||||||
// if none of the fields are or contain anything refcounted, just move on
|
// if none of the fields are or contain anything refcounted, just move on
|
||||||
if !field_layouts.iter().any(|x| {
|
if !field_layouts.iter().any(|x| {
|
||||||
let x = layout_interner.get(*x);
|
let x = layout_interner.get_repr(*x);
|
||||||
x.is_refcounted() || x.contains_refcounted(layout_interner)
|
x.is_refcounted() || x.contains_refcounted(layout_interner)
|
||||||
}) {
|
}) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1744,7 +1746,8 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
|
||||||
let block = env.context.append_basic_block(parent, "tag_id_modify");
|
let block = env.context.append_basic_block(parent, "tag_id_modify");
|
||||||
env.builder.position_at_end(block);
|
env.builder.position_at_end(block);
|
||||||
|
|
||||||
let fields_struct = layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
let fields_struct =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||||
let data_struct_type = basic_type_from_layout(env, layout_interner, fields_struct);
|
let data_struct_type = basic_type_from_layout(env, layout_interner, fields_struct);
|
||||||
|
|
||||||
debug_assert!(data_struct_type.is_struct_type());
|
debug_assert!(data_struct_type.is_struct_type());
|
||||||
|
@ -1767,7 +1770,7 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
|
||||||
|
|
||||||
for (i, field_layout) in field_layouts.iter().enumerate() {
|
for (i, field_layout) in field_layouts.iter().enumerate() {
|
||||||
if let LayoutRepr::RecursivePointer(union_layout) =
|
if let LayoutRepr::RecursivePointer(union_layout) =
|
||||||
layout_interner.get(*field_layout).repr
|
layout_interner.get_repr(*field_layout)
|
||||||
{
|
{
|
||||||
// This field is a pointer to the recursive pointer.
|
// This field is a pointer to the recursive pointer.
|
||||||
let field_ptr = env
|
let field_ptr = env
|
||||||
|
|
|
@ -507,7 +507,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
||||||
let heap_return_ptr_id = LocalId(wrapper_arg_layouts.len() as u32 - 1);
|
let heap_return_ptr_id = LocalId(wrapper_arg_layouts.len() as u32 - 1);
|
||||||
let inner_ret_layout = match wrapper_arg_layouts
|
let inner_ret_layout = match wrapper_arg_layouts
|
||||||
.last()
|
.last()
|
||||||
.map(|l| self.layout_interner.get(*l).repr)
|
.map(|l| self.layout_interner.get_repr(*l))
|
||||||
{
|
{
|
||||||
Some(LayoutRepr::Boxed(inner)) => WasmLayout::new(self.layout_interner, inner),
|
Some(LayoutRepr::Boxed(inner)) => WasmLayout::new(self.layout_interner, inner),
|
||||||
x => internal_error!("Higher-order wrapper: invalid return layout {:?}", x),
|
x => internal_error!("Higher-order wrapper: invalid return layout {:?}", x),
|
||||||
|
@ -539,7 +539,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let inner_layout = match self.layout_interner.get(*wrapper_arg).repr {
|
let inner_layout = match self.layout_interner.get_repr(*wrapper_arg) {
|
||||||
LayoutRepr::Boxed(inner) => inner,
|
LayoutRepr::Boxed(inner) => inner,
|
||||||
x => internal_error!("Expected a Boxed layout, got {:?}", x),
|
x => internal_error!("Expected a Boxed layout, got {:?}", x),
|
||||||
};
|
};
|
||||||
|
@ -558,7 +558,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
||||||
if self.layout_interner.stack_size(closure_data_layout) > 0 {
|
if self.layout_interner.stack_size(closure_data_layout) > 0 {
|
||||||
// The closure data exists, and will have been passed in to the wrapper as a
|
// The closure data exists, and will have been passed in to the wrapper as a
|
||||||
// one-element struct.
|
// one-element struct.
|
||||||
let inner_closure_data_layout = match self.layout_interner.get(closure_data_layout).repr
|
let inner_closure_data_layout = match self.layout_interner.get_repr(closure_data_layout)
|
||||||
{
|
{
|
||||||
LayoutRepr::Struct([inner]) => inner,
|
LayoutRepr::Struct([inner]) => inner,
|
||||||
other => internal_error!(
|
other => internal_error!(
|
||||||
|
@ -633,7 +633,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
||||||
n_inner_args += 1;
|
n_inner_args += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let inner_layout = match self.layout_interner.get(value_layout).repr {
|
let inner_layout = match self.layout_interner.get_repr(value_layout) {
|
||||||
LayoutRepr::Boxed(inner) => inner,
|
LayoutRepr::Boxed(inner) => inner,
|
||||||
x => internal_error!("Expected a Boxed layout, got {:?}", x),
|
x => internal_error!("Expected a Boxed layout, got {:?}", x),
|
||||||
};
|
};
|
||||||
|
@ -662,7 +662,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
||||||
fn dereference_boxed_value(&mut self, inner: InLayout) {
|
fn dereference_boxed_value(&mut self, inner: InLayout) {
|
||||||
use Align::*;
|
use Align::*;
|
||||||
|
|
||||||
match self.layout_interner.get(inner).repr {
|
match self.layout_interner.get_repr(inner) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(IntWidth::U8 | IntWidth::I8)) => {
|
LayoutRepr::Builtin(Builtin::Int(IntWidth::U8 | IntWidth::I8)) => {
|
||||||
self.code_builder.i32_load8_u(Bytes1, 0);
|
self.code_builder.i32_load8_u(Bytes1, 0);
|
||||||
}
|
}
|
||||||
|
@ -1362,7 +1362,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
||||||
arguments,
|
arguments,
|
||||||
ret_symbol,
|
ret_symbol,
|
||||||
ret_layout,
|
ret_layout,
|
||||||
ret_layout_raw: self.layout_interner.get(ret_layout),
|
ret_layout_raw: self.layout_interner.get_repr(ret_layout),
|
||||||
ret_storage: ret_storage.to_owned(),
|
ret_storage: ret_storage.to_owned(),
|
||||||
};
|
};
|
||||||
low_level_call.generate(self);
|
low_level_call.generate(self);
|
||||||
|
@ -1440,7 +1440,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
||||||
storage: &StoredValue,
|
storage: &StoredValue,
|
||||||
fields: &'a [Symbol],
|
fields: &'a [Symbol],
|
||||||
) {
|
) {
|
||||||
match self.layout_interner.get(layout).repr {
|
match self.layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Struct { .. } => {
|
LayoutRepr::Struct { .. } => {
|
||||||
match storage {
|
match storage {
|
||||||
StoredValue::StackMemory { location, size, .. } => {
|
StoredValue::StackMemory { location, size, .. } => {
|
||||||
|
@ -1898,7 +1898,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// allocate heap memory and load its data address onto the value stack
|
// allocate heap memory and load its data address onto the value stack
|
||||||
let arg_layout = match self.layout_interner.get(layout).repr {
|
let arg_layout = match self.layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Boxed(arg) => arg,
|
LayoutRepr::Boxed(arg) => arg,
|
||||||
_ => internal_error!("ExprBox should always produce a Boxed layout"),
|
_ => internal_error!("ExprBox should always produce a Boxed layout"),
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,7 +47,7 @@ impl WasmLayout {
|
||||||
|
|
||||||
let (size, alignment_bytes) = interner.stack_size_and_alignment(layout);
|
let (size, alignment_bytes) = interner.stack_size_and_alignment(layout);
|
||||||
|
|
||||||
match interner.get(layout).repr {
|
match interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Int(int_width)) => {
|
LayoutRepr::Builtin(Int(int_width)) => {
|
||||||
use IntWidth::*;
|
use IntWidth::*;
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ pub struct LowLevelCall<'a> {
|
||||||
pub arguments: &'a [Symbol],
|
pub arguments: &'a [Symbol],
|
||||||
pub ret_symbol: Symbol,
|
pub ret_symbol: Symbol,
|
||||||
pub ret_layout: InLayout<'a>,
|
pub ret_layout: InLayout<'a>,
|
||||||
pub ret_layout_raw: Layout<'a>,
|
pub ret_layout_raw: LayoutRepr<'a>,
|
||||||
pub ret_storage: StoredValue,
|
pub ret_storage: StoredValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,14 +237,14 @@ impl<'a> LowLevelCall<'a> {
|
||||||
}
|
}
|
||||||
StrGetCapacity => self.load_args_and_call_zig(backend, bitcode::STR_CAPACITY),
|
StrGetCapacity => self.load_args_and_call_zig(backend, bitcode::STR_CAPACITY),
|
||||||
StrToNum => {
|
StrToNum => {
|
||||||
let number_layout = match backend.layout_interner.get(self.ret_layout).repr {
|
let number_layout = match backend.layout_interner.get_repr(self.ret_layout) {
|
||||||
LayoutRepr::Struct(field_layouts) => field_layouts[0],
|
LayoutRepr::Struct(field_layouts) => field_layouts[0],
|
||||||
_ => {
|
_ => {
|
||||||
internal_error!("Unexpected mono layout {:?} for StrToNum", self.ret_layout)
|
internal_error!("Unexpected mono layout {:?} for StrToNum", self.ret_layout)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// match on the return layout to figure out which zig builtin we need
|
// match on the return layout to figure out which zig builtin we need
|
||||||
let intrinsic = match backend.layout_interner.get(number_layout).repr {
|
let intrinsic = match backend.layout_interner.get_repr(number_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => &bitcode::STR_TO_INT[int_width],
|
LayoutRepr::Builtin(Builtin::Int(int_width)) => &bitcode::STR_TO_INT[int_width],
|
||||||
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
LayoutRepr::Builtin(Builtin::Float(float_width)) => {
|
||||||
&bitcode::STR_TO_FLOAT[float_width]
|
&bitcode::STR_TO_FLOAT[float_width]
|
||||||
|
@ -388,14 +388,13 @@ impl<'a> LowLevelCall<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Byte offsets of each field in the return struct
|
// Byte offsets of each field in the return struct
|
||||||
let (ret_list_offset, ret_elem_offset, elem_layout) = match self.ret_layout_raw.repr
|
let (ret_list_offset, ret_elem_offset, elem_layout) = match self.ret_layout_raw {
|
||||||
{
|
|
||||||
LayoutRepr::Struct(&[f1, f2]) => {
|
LayoutRepr::Struct(&[f1, f2]) => {
|
||||||
let l1 = backend.layout_interner.get(f1);
|
let l1 = backend.layout_interner.get_repr(f1);
|
||||||
let l2 = backend.layout_interner.get(f2);
|
let l2 = backend.layout_interner.get_repr(f2);
|
||||||
match (l1.repr, l2.repr) {
|
match (l1, l2) {
|
||||||
(LayoutRepr::Builtin(Builtin::List(list_elem)), _)
|
(LayoutRepr::Builtin(Builtin::List(list_elem)), _)
|
||||||
if l2.repr == backend.layout_interner.get(list_elem).repr =>
|
if l2 == backend.layout_interner.get_repr(list_elem) =>
|
||||||
{
|
{
|
||||||
let list_offset = 0;
|
let list_offset = 0;
|
||||||
let elem_offset = LayoutRepr::Builtin(Builtin::List(list_elem))
|
let elem_offset = LayoutRepr::Builtin(Builtin::List(list_elem))
|
||||||
|
@ -403,7 +402,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
(list_offset, elem_offset, f2)
|
(list_offset, elem_offset, f2)
|
||||||
}
|
}
|
||||||
(_, LayoutRepr::Builtin(Builtin::List(list_elem)))
|
(_, LayoutRepr::Builtin(Builtin::List(list_elem)))
|
||||||
if l1.repr == backend.layout_interner.get(list_elem).repr =>
|
if l1 == backend.layout_interner.get_repr(list_elem) =>
|
||||||
{
|
{
|
||||||
let list_offset =
|
let list_offset =
|
||||||
l1.stack_size(backend.layout_interner, TARGET_INFO);
|
l1.stack_size(backend.layout_interner, TARGET_INFO);
|
||||||
|
@ -467,7 +466,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
|
|
||||||
let capacity: Symbol = self.arguments[0];
|
let capacity: Symbol = self.arguments[0];
|
||||||
let elem_layout = unwrap_list_elem_layout(self.ret_layout_raw);
|
let elem_layout = unwrap_list_elem_layout(self.ret_layout_raw);
|
||||||
let elem_layout = backend.layout_interner.get(elem_layout);
|
let elem_layout = backend.layout_interner.get_repr(elem_layout);
|
||||||
let (elem_width, elem_align) =
|
let (elem_width, elem_align) =
|
||||||
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
||||||
|
|
||||||
|
@ -506,7 +505,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
|
|
||||||
// Load monomorphization constants
|
// Load monomorphization constants
|
||||||
let elem_layout = unwrap_list_elem_layout(self.ret_layout_raw);
|
let elem_layout = unwrap_list_elem_layout(self.ret_layout_raw);
|
||||||
let elem_layout = backend.layout_interner.get(elem_layout);
|
let elem_layout = backend.layout_interner.get_repr(elem_layout);
|
||||||
let (elem_width, elem_align) =
|
let (elem_width, elem_align) =
|
||||||
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
||||||
backend.code_builder.i32_const(elem_align as i32);
|
backend.code_builder.i32_const(elem_align as i32);
|
||||||
|
@ -522,7 +521,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
let spare: Symbol = self.arguments[1];
|
let spare: Symbol = self.arguments[1];
|
||||||
|
|
||||||
let elem_layout = unwrap_list_elem_layout(self.ret_layout_raw);
|
let elem_layout = unwrap_list_elem_layout(self.ret_layout_raw);
|
||||||
let elem_layout = backend.layout_interner.get(elem_layout);
|
let elem_layout = backend.layout_interner.get_repr(elem_layout);
|
||||||
let (elem_width, elem_align) =
|
let (elem_width, elem_align) =
|
||||||
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
||||||
|
|
||||||
|
@ -563,7 +562,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
let list: Symbol = self.arguments[0];
|
let list: Symbol = self.arguments[0];
|
||||||
|
|
||||||
let elem_layout = unwrap_list_elem_layout(self.ret_layout_raw);
|
let elem_layout = unwrap_list_elem_layout(self.ret_layout_raw);
|
||||||
let elem_layout = backend.layout_interner.get(elem_layout);
|
let elem_layout = backend.layout_interner.get_repr(elem_layout);
|
||||||
let (elem_width, elem_align) =
|
let (elem_width, elem_align) =
|
||||||
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
||||||
|
|
||||||
|
@ -690,9 +689,12 @@ impl<'a> LowLevelCall<'a> {
|
||||||
|
|
||||||
// The refcount function receives a pointer to an element in the list
|
// The refcount function receives a pointer to an element in the list
|
||||||
// This is the same as a Struct containing the element
|
// This is the same as a Struct containing the element
|
||||||
let in_memory_layout = backend
|
let in_memory_layout =
|
||||||
.layout_interner
|
backend
|
||||||
.insert_no_semantic(LayoutRepr::Struct(backend.env.arena.alloc([elem_layout])));
|
.layout_interner
|
||||||
|
.insert_direct_no_semantic(LayoutRepr::Struct(
|
||||||
|
backend.env.arena.alloc([elem_layout]),
|
||||||
|
));
|
||||||
let dec_fn = backend.get_refcount_fn_index(in_memory_layout, HelperOp::Dec);
|
let dec_fn = backend.get_refcount_fn_index(in_memory_layout, HelperOp::Dec);
|
||||||
let dec_fn_ptr = backend.get_fn_ptr(dec_fn);
|
let dec_fn_ptr = backend.get_fn_ptr(dec_fn);
|
||||||
|
|
||||||
|
@ -735,9 +737,12 @@ impl<'a> LowLevelCall<'a> {
|
||||||
|
|
||||||
// The refcount function receives a pointer to an element in the list
|
// The refcount function receives a pointer to an element in the list
|
||||||
// This is the same as a Struct containing the element
|
// This is the same as a Struct containing the element
|
||||||
let in_memory_layout = backend
|
let in_memory_layout =
|
||||||
.layout_interner
|
backend
|
||||||
.insert_no_semantic(LayoutRepr::Struct(backend.env.arena.alloc([elem_layout])));
|
.layout_interner
|
||||||
|
.insert_direct_no_semantic(LayoutRepr::Struct(
|
||||||
|
backend.env.arena.alloc([elem_layout]),
|
||||||
|
));
|
||||||
let dec_fn = backend.get_refcount_fn_index(in_memory_layout, HelperOp::Dec);
|
let dec_fn = backend.get_refcount_fn_index(in_memory_layout, HelperOp::Dec);
|
||||||
let dec_fn_ptr = backend.get_fn_ptr(dec_fn);
|
let dec_fn_ptr = backend.get_fn_ptr(dec_fn);
|
||||||
|
|
||||||
|
@ -809,7 +814,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Num
|
// Num
|
||||||
NumAdd => match self.ret_layout_raw.repr {
|
NumAdd => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_ADD_OR_PANIC_INT[width])
|
self.load_args_and_call_zig(backend, &bitcode::NUM_ADD_OR_PANIC_INT[width])
|
||||||
}
|
}
|
||||||
|
@ -829,7 +834,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
_ => panic_ret_type(),
|
_ => panic_ret_type(),
|
||||||
},
|
},
|
||||||
|
|
||||||
NumAddWrap => match self.ret_layout_raw.repr {
|
NumAddWrap => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => match width {
|
LayoutRepr::Builtin(Builtin::Int(width)) => match width {
|
||||||
IntWidth::I128 | IntWidth::U128 => {
|
IntWidth::I128 | IntWidth::U128 => {
|
||||||
// TODO: don't panic
|
// TODO: don't panic
|
||||||
|
@ -869,7 +874,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
NumToStr => self.num_to_str(backend),
|
NumToStr => self.num_to_str(backend),
|
||||||
NumAddChecked => {
|
NumAddChecked => {
|
||||||
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
||||||
match backend.layout_interner.get(arg_layout).repr {
|
match backend.layout_interner.get_repr(arg_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_ADD_CHECKED_INT[width])
|
self.load_args_and_call_zig(backend, &bitcode::NUM_ADD_CHECKED_INT[width])
|
||||||
}
|
}
|
||||||
|
@ -882,7 +887,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
x => internal_error!("NumAddChecked is not defined for {:?}", x),
|
x => internal_error!("NumAddChecked is not defined for {:?}", x),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NumAddSaturated => match self.ret_layout_raw.repr {
|
NumAddSaturated => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_ADD_SATURATED_INT[width])
|
self.load_args_and_call_zig(backend, &bitcode::NUM_ADD_SATURATED_INT[width])
|
||||||
}
|
}
|
||||||
|
@ -900,7 +905,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
_ => panic_ret_type(),
|
_ => panic_ret_type(),
|
||||||
},
|
},
|
||||||
|
|
||||||
NumSub => match self.ret_layout_raw.repr {
|
NumSub => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_SUB_OR_PANIC_INT[width])
|
self.load_args_and_call_zig(backend, &bitcode::NUM_SUB_OR_PANIC_INT[width])
|
||||||
}
|
}
|
||||||
|
@ -920,7 +925,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
_ => panic_ret_type(),
|
_ => panic_ret_type(),
|
||||||
},
|
},
|
||||||
|
|
||||||
NumSubWrap => match self.ret_layout_raw.repr {
|
NumSubWrap => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => match width {
|
LayoutRepr::Builtin(Builtin::Int(width)) => match width {
|
||||||
IntWidth::I128 | IntWidth::U128 => {
|
IntWidth::I128 | IntWidth::U128 => {
|
||||||
// TODO: don't panic
|
// TODO: don't panic
|
||||||
|
@ -958,7 +963,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
},
|
},
|
||||||
NumSubChecked => {
|
NumSubChecked => {
|
||||||
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
||||||
match backend.layout_interner.get(arg_layout).repr {
|
match backend.layout_interner.get_repr(arg_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_SUB_CHECKED_INT[width])
|
self.load_args_and_call_zig(backend, &bitcode::NUM_SUB_CHECKED_INT[width])
|
||||||
}
|
}
|
||||||
|
@ -971,7 +976,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
x => internal_error!("NumSubChecked is not defined for {:?}", x),
|
x => internal_error!("NumSubChecked is not defined for {:?}", x),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NumSubSaturated => match self.ret_layout_raw.repr {
|
NumSubSaturated => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_SUB_SATURATED_INT[width])
|
self.load_args_and_call_zig(backend, &bitcode::NUM_SUB_SATURATED_INT[width])
|
||||||
}
|
}
|
||||||
|
@ -989,7 +994,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
_ => panic_ret_type(),
|
_ => panic_ret_type(),
|
||||||
},
|
},
|
||||||
|
|
||||||
NumMul => match self.ret_layout_raw.repr {
|
NumMul => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_MUL_OR_PANIC_INT[width])
|
self.load_args_and_call_zig(backend, &bitcode::NUM_MUL_OR_PANIC_INT[width])
|
||||||
}
|
}
|
||||||
|
@ -1008,7 +1013,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
}
|
}
|
||||||
_ => panic_ret_type(),
|
_ => panic_ret_type(),
|
||||||
},
|
},
|
||||||
NumMulWrap => match self.ret_layout_raw.repr {
|
NumMulWrap => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => match width {
|
LayoutRepr::Builtin(Builtin::Int(width)) => match width {
|
||||||
IntWidth::I128 | IntWidth::U128 => {
|
IntWidth::I128 | IntWidth::U128 => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_MUL_WRAP_INT[width])
|
self.load_args_and_call_zig(backend, &bitcode::NUM_MUL_WRAP_INT[width])
|
||||||
|
@ -1043,7 +1048,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
}
|
}
|
||||||
_ => panic_ret_type(),
|
_ => panic_ret_type(),
|
||||||
},
|
},
|
||||||
NumMulSaturated => match self.ret_layout_raw.repr {
|
NumMulSaturated => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_MUL_SATURATED_INT[width])
|
self.load_args_and_call_zig(backend, &bitcode::NUM_MUL_SATURATED_INT[width])
|
||||||
}
|
}
|
||||||
|
@ -1063,7 +1068,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
|
|
||||||
NumMulChecked => {
|
NumMulChecked => {
|
||||||
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
||||||
match backend.layout_interner.get(arg_layout).repr {
|
match backend.layout_interner.get_repr(arg_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_MUL_CHECKED_INT[width])
|
self.load_args_and_call_zig(backend, &bitcode::NUM_MUL_CHECKED_INT[width])
|
||||||
}
|
}
|
||||||
|
@ -1245,7 +1250,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
x => todo!("{:?} for {:?}", self.lowlevel, x),
|
x => todo!("{:?} for {:?}", self.lowlevel, x),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NumDivCeilUnchecked => match self.ret_layout_raw.repr {
|
NumDivCeilUnchecked => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_DIV_CEIL[width])
|
self.load_args_and_call_zig(backend, &bitcode::NUM_DIV_CEIL[width])
|
||||||
}
|
}
|
||||||
|
@ -1456,13 +1461,13 @@ impl<'a> LowLevelCall<'a> {
|
||||||
_ => todo!("{:?} for {:?}", self.lowlevel, self.ret_layout),
|
_ => todo!("{:?} for {:?}", self.lowlevel, self.ret_layout),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NumSin => match self.ret_layout_raw.repr {
|
NumSin => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_SIN[width]);
|
self.load_args_and_call_zig(backend, &bitcode::NUM_SIN[width]);
|
||||||
}
|
}
|
||||||
_ => panic_ret_type(),
|
_ => panic_ret_type(),
|
||||||
},
|
},
|
||||||
NumCos => match self.ret_layout_raw.repr {
|
NumCos => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_COS[width]);
|
self.load_args_and_call_zig(backend, &bitcode::NUM_COS[width]);
|
||||||
}
|
}
|
||||||
|
@ -1470,7 +1475,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
},
|
},
|
||||||
NumSqrtUnchecked => {
|
NumSqrtUnchecked => {
|
||||||
self.load_args(backend);
|
self.load_args(backend);
|
||||||
match self.ret_layout_raw.repr {
|
match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
|
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
|
||||||
backend.code_builder.f32_sqrt()
|
backend.code_builder.f32_sqrt()
|
||||||
}
|
}
|
||||||
|
@ -1480,7 +1485,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
_ => panic_ret_type(),
|
_ => panic_ret_type(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NumLogUnchecked => match self.ret_layout_raw.repr {
|
NumLogUnchecked => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_LOG[width]);
|
self.load_args_and_call_zig(backend, &bitcode::NUM_LOG[width]);
|
||||||
}
|
}
|
||||||
|
@ -1504,7 +1509,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
_ => todo!("{:?}: {:?} -> {:?}", self.lowlevel, arg_type, ret_type),
|
_ => todo!("{:?}: {:?} -> {:?}", self.lowlevel, arg_type, ret_type),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NumPow => match self.ret_layout_raw.repr {
|
NumPow => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_POW[width]);
|
self.load_args_and_call_zig(backend, &bitcode::NUM_POW[width]);
|
||||||
}
|
}
|
||||||
|
@ -1513,8 +1518,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
|
|
||||||
NumCountLeadingZeroBits => match backend
|
NumCountLeadingZeroBits => match backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.get(backend.storage.symbol_layouts[&self.arguments[0]])
|
.get_repr(backend.storage.symbol_layouts[&self.arguments[0]])
|
||||||
.repr
|
|
||||||
{
|
{
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(
|
self.load_args_and_call_zig(
|
||||||
|
@ -1526,8 +1530,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
},
|
},
|
||||||
NumCountTrailingZeroBits => match backend
|
NumCountTrailingZeroBits => match backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.get(backend.storage.symbol_layouts[&self.arguments[0]])
|
.get_repr(backend.storage.symbol_layouts[&self.arguments[0]])
|
||||||
.repr
|
|
||||||
{
|
{
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(
|
self.load_args_and_call_zig(
|
||||||
|
@ -1539,8 +1542,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
},
|
},
|
||||||
NumCountOneBits => match backend
|
NumCountOneBits => match backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.get(backend.storage.symbol_layouts[&self.arguments[0]])
|
.get_repr(backend.storage.symbol_layouts[&self.arguments[0]])
|
||||||
.repr
|
|
||||||
{
|
{
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_COUNT_ONE_BITS[width]);
|
self.load_args_and_call_zig(backend, &bitcode::NUM_COUNT_ONE_BITS[width]);
|
||||||
|
@ -1617,19 +1619,19 @@ impl<'a> LowLevelCall<'a> {
|
||||||
NumIsInfinite => num_is_infinite(backend, self.arguments[0]),
|
NumIsInfinite => num_is_infinite(backend, self.arguments[0]),
|
||||||
NumIsFinite => num_is_finite(backend, self.arguments[0]),
|
NumIsFinite => num_is_finite(backend, self.arguments[0]),
|
||||||
|
|
||||||
NumAtan => match self.ret_layout_raw.repr {
|
NumAtan => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_ATAN[width]);
|
self.load_args_and_call_zig(backend, &bitcode::NUM_ATAN[width]);
|
||||||
}
|
}
|
||||||
_ => panic_ret_type(),
|
_ => panic_ret_type(),
|
||||||
},
|
},
|
||||||
NumAcos => match self.ret_layout_raw.repr {
|
NumAcos => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_ACOS[width]);
|
self.load_args_and_call_zig(backend, &bitcode::NUM_ACOS[width]);
|
||||||
}
|
}
|
||||||
_ => panic_ret_type(),
|
_ => panic_ret_type(),
|
||||||
},
|
},
|
||||||
NumAsin => match self.ret_layout_raw.repr {
|
NumAsin => match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
LayoutRepr::Builtin(Builtin::Float(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::NUM_ASIN[width]);
|
self.load_args_and_call_zig(backend, &bitcode::NUM_ASIN[width]);
|
||||||
}
|
}
|
||||||
|
@ -1777,14 +1779,14 @@ impl<'a> LowLevelCall<'a> {
|
||||||
NumIntCast => {
|
NumIntCast => {
|
||||||
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
||||||
let arg_type = CodeGenNumType::from(arg_layout);
|
let arg_type = CodeGenNumType::from(arg_layout);
|
||||||
let arg_width = match backend.layout_interner.get(arg_layout).repr {
|
let arg_width = match backend.layout_interner.get_repr(arg_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(w)) => w,
|
LayoutRepr::Builtin(Builtin::Int(w)) => w,
|
||||||
LayoutRepr::Builtin(Builtin::Bool) => IntWidth::U8,
|
LayoutRepr::Builtin(Builtin::Bool) => IntWidth::U8,
|
||||||
x => internal_error!("Num.intCast is not defined for {:?}", x),
|
x => internal_error!("Num.intCast is not defined for {:?}", x),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ret_type = CodeGenNumType::from(self.ret_layout);
|
let ret_type = CodeGenNumType::from(self.ret_layout);
|
||||||
let ret_width = match self.ret_layout_raw.repr {
|
let ret_width = match self.ret_layout_raw {
|
||||||
LayoutRepr::Builtin(Builtin::Int(w)) => w,
|
LayoutRepr::Builtin(Builtin::Int(w)) => w,
|
||||||
x => internal_error!("Num.intCast is not defined for {:?}", x),
|
x => internal_error!("Num.intCast is not defined for {:?}", x),
|
||||||
};
|
};
|
||||||
|
@ -1847,7 +1849,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
NumToFloatCast => {
|
NumToFloatCast => {
|
||||||
self.load_args(backend);
|
self.load_args(backend);
|
||||||
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
||||||
let arg_signed = match backend.layout_interner.get(arg_layout).repr {
|
let arg_signed = match backend.layout_interner.get_repr(arg_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(w)) => w.is_signed(),
|
LayoutRepr::Builtin(Builtin::Int(w)) => w.is_signed(),
|
||||||
LayoutRepr::Builtin(Builtin::Float(_)) => true, // unused
|
LayoutRepr::Builtin(Builtin::Float(_)) => true, // unused
|
||||||
LayoutRepr::Builtin(Builtin::Decimal) => true,
|
LayoutRepr::Builtin(Builtin::Decimal) => true,
|
||||||
|
@ -1895,13 +1897,13 @@ impl<'a> LowLevelCall<'a> {
|
||||||
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
||||||
|
|
||||||
let (arg_width, ret_width) = match (
|
let (arg_width, ret_width) = match (
|
||||||
backend.layout_interner.get(arg_layout).repr,
|
backend.layout_interner.get_repr(arg_layout),
|
||||||
self.ret_layout_raw.repr,
|
self.ret_layout_raw,
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
LayoutRepr::Builtin(Builtin::Int(arg_width)),
|
LayoutRepr::Builtin(Builtin::Int(arg_width)),
|
||||||
LayoutRepr::Struct(&[ret, ..]),
|
LayoutRepr::Struct(&[ret, ..]),
|
||||||
) => match backend.layout_interner.get(ret).repr {
|
) => match backend.layout_interner.get_repr(ret) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(ret_width)) => (arg_width, ret_width),
|
LayoutRepr::Builtin(Builtin::Int(ret_width)) => (arg_width, ret_width),
|
||||||
_ => {
|
_ => {
|
||||||
internal_error!(
|
internal_error!(
|
||||||
|
@ -1993,19 +1995,19 @@ impl<'a> LowLevelCall<'a> {
|
||||||
let arg_layout = backend
|
let arg_layout = backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.runtime_representation_in(backend.storage.symbol_layouts[&self.arguments[0]]);
|
.runtime_representation_in(backend.storage.symbol_layouts[&self.arguments[0]]);
|
||||||
let arg_layout_raw = backend.layout_interner.get(arg_layout);
|
let arg_layout_raw = backend.layout_interner.get_repr(arg_layout);
|
||||||
let other_arg_layout = backend
|
let other_arg_layout = backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.runtime_representation(backend.storage.symbol_layouts[&self.arguments[1]]);
|
.runtime_representation(backend.storage.symbol_layouts[&self.arguments[1]]);
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
arg_layout_raw.repr, other_arg_layout.repr,
|
arg_layout_raw, other_arg_layout,
|
||||||
"Cannot do `==` comparison on different types: {:?} vs {:?}",
|
"Cannot do `==` comparison on different types: {:?} vs {:?}",
|
||||||
arg_layout, other_arg_layout
|
arg_layout, other_arg_layout
|
||||||
);
|
);
|
||||||
|
|
||||||
let invert_result = matches!(self.lowlevel, LowLevel::NotEq);
|
let invert_result = matches!(self.lowlevel, LowLevel::NotEq);
|
||||||
|
|
||||||
match arg_layout_raw.repr {
|
match arg_layout_raw {
|
||||||
LayoutRepr::Builtin(
|
LayoutRepr::Builtin(
|
||||||
Builtin::Int(_) | Builtin::Float(_) | Builtin::Bool | Builtin::Decimal,
|
Builtin::Int(_) | Builtin::Float(_) | Builtin::Bool | Builtin::Decimal,
|
||||||
) => self.eq_or_neq_number(backend),
|
) => self.eq_or_neq_number(backend),
|
||||||
|
@ -2147,7 +2149,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
|
|
||||||
fn num_to_str(&self, backend: &mut WasmBackend<'a, '_>) {
|
fn num_to_str(&self, backend: &mut WasmBackend<'a, '_>) {
|
||||||
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
||||||
match backend.layout_interner.get(arg_layout).repr {
|
match backend.layout_interner.get_repr(arg_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
LayoutRepr::Builtin(Builtin::Int(width)) => {
|
||||||
self.load_args_and_call_zig(backend, &bitcode::STR_FROM_INT[width])
|
self.load_args_and_call_zig(backend, &bitcode::STR_FROM_INT[width])
|
||||||
}
|
}
|
||||||
|
@ -2355,8 +2357,7 @@ pub fn call_higher_order_lowlevel<'a>(
|
||||||
// The wrapper around the passed function will access the actual closure data in the struct.
|
// The wrapper around the passed function will access the actual closure data in the struct.
|
||||||
let (closure_data_layout, closure_data_exists) = match backend
|
let (closure_data_layout, closure_data_exists) = match backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.get(backend.storage.symbol_layouts[captured_environment])
|
.get_repr(backend.storage.symbol_layouts[captured_environment])
|
||||||
.repr
|
|
||||||
{
|
{
|
||||||
LayoutRepr::LambdaSet(lambda_set) => {
|
LayoutRepr::LambdaSet(lambda_set) => {
|
||||||
if lambda_set.is_represented(backend.layout_interner).is_some() {
|
if lambda_set.is_represented(backend.layout_interner).is_some() {
|
||||||
|
@ -2379,7 +2380,7 @@ pub fn call_higher_order_lowlevel<'a>(
|
||||||
let wrapped_captures_layout =
|
let wrapped_captures_layout =
|
||||||
backend
|
backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.insert_no_semantic(LayoutRepr::struct_(
|
.insert_direct_no_semantic(LayoutRepr::struct_(
|
||||||
backend.env.arena.alloc([closure_data_layout]),
|
backend.env.arena.alloc([closure_data_layout]),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -2454,7 +2455,7 @@ pub fn call_higher_order_lowlevel<'a>(
|
||||||
argument_layouts.iter().take(n_non_closure_args).map(|lay| {
|
argument_layouts.iter().take(n_non_closure_args).map(|lay| {
|
||||||
backend
|
backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.insert_no_semantic(LayoutRepr::Boxed(*lay))
|
.insert_direct_no_semantic(LayoutRepr::Boxed(*lay))
|
||||||
});
|
});
|
||||||
|
|
||||||
wrapper_arg_layouts.push(wrapped_captures_layout);
|
wrapper_arg_layouts.push(wrapped_captures_layout);
|
||||||
|
@ -2466,7 +2467,7 @@ pub fn call_higher_order_lowlevel<'a>(
|
||||||
wrapper_arg_layouts.push(
|
wrapper_arg_layouts.push(
|
||||||
backend
|
backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.insert_no_semantic(LayoutRepr::Boxed(*result_layout)),
|
.insert_direct_no_semantic(LayoutRepr::Boxed(*result_layout)),
|
||||||
);
|
);
|
||||||
ProcLayout {
|
ProcLayout {
|
||||||
arguments: wrapper_arg_layouts.into_bump_slice(),
|
arguments: wrapper_arg_layouts.into_bump_slice(),
|
||||||
|
@ -2556,9 +2557,9 @@ pub fn call_higher_order_lowlevel<'a>(
|
||||||
let elem_layout = unwrap_list_elem_layout(
|
let elem_layout = unwrap_list_elem_layout(
|
||||||
backend
|
backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.get(backend.storage.symbol_layouts[xs]),
|
.get_repr(backend.storage.symbol_layouts[xs]),
|
||||||
);
|
);
|
||||||
let elem_layout = backend.layout_interner.get(elem_layout);
|
let elem_layout = backend.layout_interner.get_repr(elem_layout);
|
||||||
let (element_width, alignment) =
|
let (element_width, alignment) =
|
||||||
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
||||||
|
|
||||||
|
@ -2595,8 +2596,8 @@ pub fn call_higher_order_lowlevel<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unwrap_list_elem_layout(list_layout: Layout) -> InLayout {
|
fn unwrap_list_elem_layout(list_layout: LayoutRepr) -> InLayout {
|
||||||
match list_layout.repr {
|
match list_layout {
|
||||||
LayoutRepr::Builtin(Builtin::List(x)) => x,
|
LayoutRepr::Builtin(Builtin::List(x)) => x,
|
||||||
e => internal_error!("expected List layout, got {:?}", e),
|
e => internal_error!("expected List layout, got {:?}", e),
|
||||||
}
|
}
|
||||||
|
@ -2620,14 +2621,14 @@ fn list_map_n<'a>(
|
||||||
unwrap_list_elem_layout(
|
unwrap_list_elem_layout(
|
||||||
backend
|
backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.get(backend.storage.symbol_layouts[sym]),
|
.get_repr(backend.storage.symbol_layouts[sym]),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
backend.env.arena,
|
backend.env.arena,
|
||||||
);
|
);
|
||||||
|
|
||||||
let elem_ret = unwrap_list_elem_layout(backend.layout_interner.get(return_layout));
|
let elem_ret = unwrap_list_elem_layout(backend.layout_interner.get_repr(return_layout));
|
||||||
let elem_ret = backend.layout_interner.get(elem_ret);
|
let elem_ret = backend.layout_interner.get_repr(elem_ret);
|
||||||
let (elem_ret_size, elem_ret_align) =
|
let (elem_ret_size, elem_ret_align) =
|
||||||
elem_ret.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
elem_ret.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
||||||
|
|
||||||
|
@ -2661,7 +2662,7 @@ fn list_map_n<'a>(
|
||||||
// Here we wrap the layout in a Struct to ensure we get the right code gen
|
// Here we wrap the layout in a Struct to ensure we get the right code gen
|
||||||
let el_ptr = backend
|
let el_ptr = backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.insert_no_semantic(LayoutRepr::Struct(backend.env.arena.alloc([*el])));
|
.insert_direct_no_semantic(LayoutRepr::Struct(backend.env.arena.alloc([*el])));
|
||||||
let idx = backend.get_refcount_fn_index(el_ptr, HelperOp::Dec);
|
let idx = backend.get_refcount_fn_index(el_ptr, HelperOp::Dec);
|
||||||
let ptr = backend.get_fn_ptr(idx);
|
let ptr = backend.get_fn_ptr(idx);
|
||||||
backend.code_builder.i32_const(ptr);
|
backend.code_builder.i32_const(ptr);
|
||||||
|
@ -2700,7 +2701,7 @@ fn ensure_symbol_is_in_memory<'a>(
|
||||||
);
|
);
|
||||||
let in_memory_layout = backend
|
let in_memory_layout = backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.insert_no_semantic(LayoutRepr::Struct(arena.alloc([layout])));
|
.insert_direct_no_semantic(LayoutRepr::Struct(arena.alloc([layout])));
|
||||||
(frame_ptr, offset, in_memory_layout)
|
(frame_ptr, offset, in_memory_layout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub fn insert_wrapper_for_layout<'a>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match interner.get(layout).repr {
|
match interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(IntWidth::U8 | IntWidth::I8)) => {
|
LayoutRepr::Builtin(Builtin::Int(IntWidth::U8 | IntWidth::I8)) => {
|
||||||
i8::insert_wrapper(arena, module, wrapper_name, main_fn_index);
|
i8::insert_wrapper(arena, module, wrapper_name, main_fn_index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::hash::Hash;
|
||||||
use crate::ir::{
|
use crate::ir::{
|
||||||
Expr, HigherOrderLowLevel, JoinPointId, Param, PassedFunction, Proc, ProcLayout, Stmt,
|
Expr, HigherOrderLowLevel, JoinPointId, Param, PassedFunction, Proc, ProcLayout, Stmt,
|
||||||
};
|
};
|
||||||
use crate::layout::{InLayout, Layout, LayoutInterner, STLayoutInterner};
|
use crate::layout::{InLayout, LayoutInterner, LayoutRepr, STLayoutInterner};
|
||||||
use bumpalo::collections::Vec;
|
use bumpalo::collections::Vec;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use roc_collections::all::{MutMap, MutSet};
|
use roc_collections::all::{MutMap, MutSet};
|
||||||
|
@ -29,7 +29,7 @@ impl Ownership {
|
||||||
|
|
||||||
/// For reference-counted types (lists, (big) strings, recursive tags), owning a value
|
/// For reference-counted types (lists, (big) strings, recursive tags), owning a value
|
||||||
/// means incrementing its reference count. Hence, we prefer borrowing for these types
|
/// means incrementing its reference count. Hence, we prefer borrowing for these types
|
||||||
fn from_layout(layout: &Layout) -> Self {
|
fn from_layout(layout: &LayoutRepr) -> Self {
|
||||||
match layout.is_refcounted() {
|
match layout.is_refcounted() {
|
||||||
true => Ownership::Borrowed,
|
true => Ownership::Borrowed,
|
||||||
false => Ownership::Owned,
|
false => Ownership::Owned,
|
||||||
|
@ -265,7 +265,7 @@ impl<'a> ParamMap<'a> {
|
||||||
) -> &'a [Param<'a>] {
|
) -> &'a [Param<'a>] {
|
||||||
Vec::from_iter_in(
|
Vec::from_iter_in(
|
||||||
ps.iter().map(|p| Param {
|
ps.iter().map(|p| Param {
|
||||||
ownership: Ownership::from_layout(&interner.get(p.layout)),
|
ownership: Ownership::from_layout(&interner.get_repr(p.layout)),
|
||||||
layout: p.layout,
|
layout: p.layout,
|
||||||
symbol: p.symbol,
|
symbol: p.symbol,
|
||||||
}),
|
}),
|
||||||
|
@ -281,7 +281,7 @@ impl<'a> ParamMap<'a> {
|
||||||
) -> &'a [Param<'a>] {
|
) -> &'a [Param<'a>] {
|
||||||
Vec::from_iter_in(
|
Vec::from_iter_in(
|
||||||
ps.iter().map(|(layout, symbol)| Param {
|
ps.iter().map(|(layout, symbol)| Param {
|
||||||
ownership: Ownership::from_layout(&interner.get(*layout)),
|
ownership: Ownership::from_layout(&interner.get_repr(*layout)),
|
||||||
layout: *layout,
|
layout: *layout,
|
||||||
symbol: *symbol,
|
symbol: *symbol,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub fn eq_generic<'a>(
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
use crate::layout::Builtin::*;
|
use crate::layout::Builtin::*;
|
||||||
use LayoutRepr::*;
|
use LayoutRepr::*;
|
||||||
let main_body = match layout_interner.get(layout).repr {
|
let main_body = match layout_interner.get_repr(layout) {
|
||||||
Builtin(Int(_) | Float(_) | Bool | Decimal) => {
|
Builtin(Int(_) | Float(_) | Bool | Decimal) => {
|
||||||
unreachable!(
|
unreachable!(
|
||||||
"No generated proc for `==`. Use direct code gen for {:?}",
|
"No generated proc for `==`. Use direct code gen for {:?}",
|
||||||
|
@ -434,7 +434,8 @@ fn eq_tag_union_help<'a>(
|
||||||
if is_non_recursive {
|
if is_non_recursive {
|
||||||
compare_ptr_or_value
|
compare_ptr_or_value
|
||||||
} else {
|
} else {
|
||||||
let union_layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
let union_layout =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
let loop_params_iter = operands.iter().map(|arg| Param {
|
let loop_params_iter = operands.iter().map(|arg| Param {
|
||||||
symbol: *arg,
|
symbol: *arg,
|
||||||
ownership: Ownership::Borrowed,
|
ownership: Ownership::Borrowed,
|
||||||
|
@ -468,7 +469,7 @@ fn eq_tag_fields<'a>(
|
||||||
// (If there are more than one, the others will use non-tail recursion)
|
// (If there are more than one, the others will use non-tail recursion)
|
||||||
let rec_ptr_index = field_layouts.iter().position(|field| {
|
let rec_ptr_index = field_layouts.iter().position(|field| {
|
||||||
matches!(
|
matches!(
|
||||||
layout_interner.get(*field).repr,
|
layout_interner.get_repr(*field),
|
||||||
LayoutRepr::RecursivePointer(_)
|
LayoutRepr::RecursivePointer(_)
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -657,7 +658,7 @@ fn eq_list<'a>(
|
||||||
let arena = root.arena;
|
let arena = root.arena;
|
||||||
|
|
||||||
// A "Box" layout (heap pointer to a single list element)
|
// A "Box" layout (heap pointer to a single list element)
|
||||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(elem_layout));
|
let box_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(elem_layout));
|
||||||
|
|
||||||
// Compare lengths
|
// Compare lengths
|
||||||
|
|
||||||
|
@ -703,7 +704,7 @@ fn eq_list<'a>(
|
||||||
let size = root.create_symbol(ident_ids, "size");
|
let size = root.create_symbol(ident_ids, "size");
|
||||||
let size_expr = Expr::Literal(Literal::Int(
|
let size_expr = Expr::Literal(Literal::Int(
|
||||||
(layout_interner
|
(layout_interner
|
||||||
.get(elem_layout)
|
.get_repr(elem_layout)
|
||||||
.stack_size(layout_interner, root.target_info) as i128)
|
.stack_size(layout_interner, root.target_info) as i128)
|
||||||
.to_ne_bytes(),
|
.to_ne_bytes(),
|
||||||
));
|
));
|
||||||
|
|
|
@ -10,8 +10,8 @@ use crate::ir::{
|
||||||
Proc, ProcLayout, SelfRecursive, Stmt, UpdateModeId,
|
Proc, ProcLayout, SelfRecursive, Stmt, UpdateModeId,
|
||||||
};
|
};
|
||||||
use crate::layout::{
|
use crate::layout::{
|
||||||
Builtin, InLayout, LambdaName, Layout, LayoutInterner, LayoutRepr, Niche, STLayoutInterner,
|
Builtin, InLayout, LambdaName, Layout, LayoutInterner, LayoutRepr, LayoutWrapper, Niche,
|
||||||
UnionLayout,
|
STLayoutInterner, UnionLayout,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod equality;
|
mod equality;
|
||||||
|
@ -286,11 +286,11 @@ impl<'a> CodeGenHelp<'a> {
|
||||||
self.debug_recursion_depth += 1;
|
self.debug_recursion_depth += 1;
|
||||||
|
|
||||||
let layout = if matches!(
|
let layout = if matches!(
|
||||||
layout_interner.get(called_layout).repr,
|
layout_interner.get_repr(called_layout),
|
||||||
LayoutRepr::RecursivePointer(_)
|
LayoutRepr::RecursivePointer(_)
|
||||||
) {
|
) {
|
||||||
let union_layout = ctx.recursive_union.unwrap();
|
let union_layout = ctx.recursive_union.unwrap();
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout))
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout))
|
||||||
} else {
|
} else {
|
||||||
called_layout
|
called_layout
|
||||||
};
|
};
|
||||||
|
@ -301,7 +301,7 @@ impl<'a> CodeGenHelp<'a> {
|
||||||
|
|
||||||
let (ret_layout, arg_layouts): (InLayout<'a>, &'a [InLayout<'a>]) = {
|
let (ret_layout, arg_layouts): (InLayout<'a>, &'a [InLayout<'a>]) = {
|
||||||
let arg = self.replace_rec_ptr(ctx, layout_interner, layout);
|
let arg = self.replace_rec_ptr(ctx, layout_interner, layout);
|
||||||
let box_arg = layout_interner.insert_no_semantic(LayoutRepr::Boxed(arg));
|
let box_arg = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(arg));
|
||||||
|
|
||||||
match ctx.op {
|
match ctx.op {
|
||||||
Dec | DecRef(_) => (LAYOUT_UNIT, self.arena.alloc([arg])),
|
Dec | DecRef(_) => (LAYOUT_UNIT, self.arena.alloc([arg])),
|
||||||
|
@ -430,12 +430,14 @@ impl<'a> CodeGenHelp<'a> {
|
||||||
}
|
}
|
||||||
Dec | DecRef(_) | Reset | ResetRef => self.arena.alloc([roc_value]),
|
Dec | DecRef(_) | Reset | ResetRef => self.arena.alloc([roc_value]),
|
||||||
IndirectInc => {
|
IndirectInc => {
|
||||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(layout));
|
let box_layout =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
|
||||||
let inc_amount = (self.layout_isize, ARG_2);
|
let inc_amount = (self.layout_isize, ARG_2);
|
||||||
self.arena.alloc([(box_layout, ARG_1), inc_amount])
|
self.arena.alloc([(box_layout, ARG_1), inc_amount])
|
||||||
}
|
}
|
||||||
IndirectDec => {
|
IndirectDec => {
|
||||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(layout));
|
let box_layout =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
|
||||||
self.arena.alloc([(box_layout, ARG_1)])
|
self.arena.alloc([(box_layout, ARG_1)])
|
||||||
}
|
}
|
||||||
Eq => self.arena.alloc([roc_value, (layout, ARG_2)]),
|
Eq => self.arena.alloc([roc_value, (layout, ARG_2)]),
|
||||||
|
@ -483,7 +485,8 @@ impl<'a> CodeGenHelp<'a> {
|
||||||
niche: Niche::NONE,
|
niche: Niche::NONE,
|
||||||
},
|
},
|
||||||
HelperOp::IndirectInc => {
|
HelperOp::IndirectInc => {
|
||||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(layout));
|
let box_layout =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
|
||||||
|
|
||||||
ProcLayout {
|
ProcLayout {
|
||||||
arguments: self.arena.alloc([box_layout, self.layout_isize]),
|
arguments: self.arena.alloc([box_layout, self.layout_isize]),
|
||||||
|
@ -492,7 +495,8 @@ impl<'a> CodeGenHelp<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HelperOp::IndirectDec => {
|
HelperOp::IndirectDec => {
|
||||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(layout));
|
let box_layout =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
|
||||||
|
|
||||||
ProcLayout {
|
ProcLayout {
|
||||||
arguments: self.arena.alloc([box_layout]),
|
arguments: self.arena.alloc([box_layout]),
|
||||||
|
@ -532,8 +536,9 @@ impl<'a> CodeGenHelp<'a> {
|
||||||
layout_interner: &mut STLayoutInterner<'a>,
|
layout_interner: &mut STLayoutInterner<'a>,
|
||||||
layout: InLayout<'a>,
|
layout: InLayout<'a>,
|
||||||
) -> InLayout<'a> {
|
) -> InLayout<'a> {
|
||||||
let lay = layout_interner.get(layout);
|
let lay = layout_interner.get_repr(layout);
|
||||||
let repr = match lay.repr {
|
let semantic = layout_interner.get_semantic(layout);
|
||||||
|
let repr = match lay {
|
||||||
LayoutRepr::Builtin(Builtin::List(v)) => {
|
LayoutRepr::Builtin(Builtin::List(v)) => {
|
||||||
let v = self.replace_rec_ptr(ctx, layout_interner, v);
|
let v = self.replace_rec_ptr(ctx, layout_interner, v);
|
||||||
LayoutRepr::Builtin(Builtin::List(v))
|
LayoutRepr::Builtin(Builtin::List(v))
|
||||||
|
@ -580,7 +585,7 @@ impl<'a> CodeGenHelp<'a> {
|
||||||
LayoutRepr::RecursivePointer(_) => LayoutRepr::Union(ctx.recursive_union.unwrap()),
|
LayoutRepr::RecursivePointer(_) => LayoutRepr::Union(ctx.recursive_union.unwrap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
layout_interner.insert(Layout::new(repr, lay.semantic()))
|
layout_interner.insert(Layout::new(LayoutWrapper::Direct(repr), semantic))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn union_tail_recursion_fields(
|
fn union_tail_recursion_fields(
|
||||||
|
@ -664,16 +669,16 @@ impl<'a> CallerProc<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let box_capture_layout = if let Some(capture_layout) = capture_layout {
|
let box_capture_layout = if let Some(capture_layout) = capture_layout {
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::Boxed(capture_layout))
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(capture_layout))
|
||||||
} else {
|
} else {
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::Boxed(Layout::UNIT))
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(Layout::UNIT))
|
||||||
};
|
};
|
||||||
|
|
||||||
let box_argument_layout = layout_interner
|
let box_argument_layout = layout_interner
|
||||||
.insert_no_semantic(LayoutRepr::Boxed(passed_function.argument_layouts[0]));
|
.insert_direct_no_semantic(LayoutRepr::Boxed(passed_function.argument_layouts[0]));
|
||||||
|
|
||||||
let box_return_layout =
|
let box_return_layout = layout_interner
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::Boxed(passed_function.return_layout));
|
.insert_direct_no_semantic(LayoutRepr::Boxed(passed_function.return_layout));
|
||||||
|
|
||||||
let proc_layout = ProcLayout {
|
let proc_layout = ProcLayout {
|
||||||
arguments: arena.alloc([box_capture_layout, box_argument_layout, box_return_layout]),
|
arguments: arena.alloc([box_capture_layout, box_argument_layout, box_return_layout]),
|
||||||
|
@ -822,7 +827,7 @@ fn layout_needs_helper_proc<'a>(
|
||||||
layout: InLayout<'a>,
|
layout: InLayout<'a>,
|
||||||
op: HelperOp,
|
op: HelperOp,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(
|
LayoutRepr::Builtin(
|
||||||
Builtin::Int(_) | Builtin::Float(_) | Builtin::Bool | Builtin::Decimal,
|
Builtin::Int(_) | Builtin::Float(_) | Builtin::Bool | Builtin::Decimal,
|
||||||
) => false,
|
) => false,
|
||||||
|
|
|
@ -75,7 +75,7 @@ pub fn refcount_stmt<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
ModifyRc::DecRef(structure) => {
|
ModifyRc::DecRef(structure) => {
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get_repr(layout) {
|
||||||
// Str has no children, so Dec is the same as DecRef.
|
// Str has no children, so Dec is the same as DecRef.
|
||||||
LayoutRepr::Builtin(Builtin::Str) => {
|
LayoutRepr::Builtin(Builtin::Str) => {
|
||||||
ctx.op = HelperOp::Dec;
|
ctx.op = HelperOp::Dec;
|
||||||
|
@ -182,7 +182,7 @@ pub fn refcount_generic<'a>(
|
||||||
layout: InLayout<'a>,
|
layout: InLayout<'a>,
|
||||||
structure: Symbol,
|
structure: Symbol,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(
|
LayoutRepr::Builtin(
|
||||||
Builtin::Int(_) | Builtin::Float(_) | Builtin::Bool | Builtin::Decimal,
|
Builtin::Int(_) | Builtin::Float(_) | Builtin::Bool | Builtin::Decimal,
|
||||||
) => {
|
) => {
|
||||||
|
@ -301,7 +301,7 @@ pub fn refcount_reset_proc_body<'a>(
|
||||||
let is_unique = root.create_symbol(ident_ids, "is_unique");
|
let is_unique = root.create_symbol(ident_ids, "is_unique");
|
||||||
let addr = root.create_symbol(ident_ids, "addr");
|
let addr = root.create_symbol(ident_ids, "addr");
|
||||||
|
|
||||||
let union_layout = match layout_interner.get(layout).repr {
|
let union_layout = match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Union(u) => u,
|
LayoutRepr::Union(u) => u,
|
||||||
_ => unimplemented!("Reset is only implemented for UnionLayout"),
|
_ => unimplemented!("Reset is only implemented for UnionLayout"),
|
||||||
};
|
};
|
||||||
|
@ -309,7 +309,8 @@ pub fn refcount_reset_proc_body<'a>(
|
||||||
// Whenever we recurse into a child layout we will want to Decrement
|
// Whenever we recurse into a child layout we will want to Decrement
|
||||||
ctx.op = HelperOp::Dec;
|
ctx.op = HelperOp::Dec;
|
||||||
ctx.recursive_union = Some(union_layout);
|
ctx.recursive_union = Some(union_layout);
|
||||||
let recursion_ptr = layout_interner.insert_no_semantic(LayoutRepr::RecursivePointer(layout));
|
let recursion_ptr =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::RecursivePointer(layout));
|
||||||
|
|
||||||
// Reset structure is unique. Decrement its children and return a pointer to the allocation.
|
// Reset structure is unique. Decrement its children and return a pointer to the allocation.
|
||||||
let then_stmt = {
|
let then_stmt = {
|
||||||
|
@ -483,7 +484,7 @@ pub fn refcount_resetref_proc_body<'a>(
|
||||||
let is_unique = root.create_symbol(ident_ids, "is_unique");
|
let is_unique = root.create_symbol(ident_ids, "is_unique");
|
||||||
let addr = root.create_symbol(ident_ids, "addr");
|
let addr = root.create_symbol(ident_ids, "addr");
|
||||||
|
|
||||||
let union_layout = match layout_interner.get(layout).repr {
|
let union_layout = match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Union(u) => u,
|
LayoutRepr::Union(u) => u,
|
||||||
_ => unimplemented!("Resetref is only implemented for UnionLayout"),
|
_ => unimplemented!("Resetref is only implemented for UnionLayout"),
|
||||||
};
|
};
|
||||||
|
@ -491,7 +492,8 @@ pub fn refcount_resetref_proc_body<'a>(
|
||||||
// Whenever we recurse into a child layout we will want to Decrement
|
// Whenever we recurse into a child layout we will want to Decrement
|
||||||
ctx.op = HelperOp::Dec;
|
ctx.op = HelperOp::Dec;
|
||||||
ctx.recursive_union = Some(union_layout);
|
ctx.recursive_union = Some(union_layout);
|
||||||
let recursion_ptr = layout_interner.insert_no_semantic(LayoutRepr::RecursivePointer(layout));
|
let recursion_ptr =
|
||||||
|
layout_interner.insert_direct_no_semantic(LayoutRepr::RecursivePointer(layout));
|
||||||
|
|
||||||
// Reset structure is unique. Return a pointer to the allocation.
|
// Reset structure is unique. Return a pointer to the allocation.
|
||||||
let then_stmt = Stmt::Ret(addr);
|
let then_stmt = Stmt::Ret(addr);
|
||||||
|
@ -979,7 +981,7 @@ fn refcount_list<'a>(
|
||||||
let arena = root.arena;
|
let arena = root.arena;
|
||||||
|
|
||||||
// A "Box" layout (heap pointer to a single list element)
|
// A "Box" layout (heap pointer to a single list element)
|
||||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(elem_layout));
|
let box_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(elem_layout));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check if the list is empty
|
// Check if the list is empty
|
||||||
|
@ -1106,7 +1108,7 @@ fn refcount_list<'a>(
|
||||||
|
|
||||||
let is_relevant_op = ctx.op.is_dec() || ctx.op.is_inc();
|
let is_relevant_op = ctx.op.is_dec() || ctx.op.is_inc();
|
||||||
let modify_elems_and_list =
|
let modify_elems_and_list =
|
||||||
if is_relevant_op && layout_interner.get(elem_layout).is_refcounted() {
|
if is_relevant_op && layout_interner.get_repr(elem_layout).is_refcounted() {
|
||||||
refcount_list_elems(
|
refcount_list_elems(
|
||||||
root,
|
root,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
|
@ -1742,7 +1744,7 @@ fn refcount_union_tailrec<'a>(
|
||||||
let tailrec_loop = JoinPointId(root.create_symbol(ident_ids, "tailrec_loop"));
|
let tailrec_loop = JoinPointId(root.create_symbol(ident_ids, "tailrec_loop"));
|
||||||
let current = root.create_symbol(ident_ids, "current");
|
let current = root.create_symbol(ident_ids, "current");
|
||||||
let next_ptr = root.create_symbol(ident_ids, "next_ptr");
|
let next_ptr = root.create_symbol(ident_ids, "next_ptr");
|
||||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
|
|
||||||
let tag_id_layout = union_layout.tag_id_layout();
|
let tag_id_layout = union_layout.tag_id_layout();
|
||||||
|
|
||||||
|
@ -1887,7 +1889,7 @@ fn refcount_union_tailrec<'a>(
|
||||||
let jump_with_null_ptr = Stmt::Let(
|
let jump_with_null_ptr = Stmt::Let(
|
||||||
null_pointer,
|
null_pointer,
|
||||||
Expr::NullPointer,
|
Expr::NullPointer,
|
||||||
layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout)),
|
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout)),
|
||||||
root.arena.alloc(Stmt::Jump(
|
root.arena.alloc(Stmt::Jump(
|
||||||
jp_modify_union,
|
jp_modify_union,
|
||||||
root.arena.alloc([null_pointer]),
|
root.arena.alloc([null_pointer]),
|
||||||
|
@ -1931,7 +1933,7 @@ fn refcount_union_tailrec<'a>(
|
||||||
));
|
));
|
||||||
|
|
||||||
let loop_init = Stmt::Jump(tailrec_loop, root.arena.alloc([initial_structure]));
|
let loop_init = Stmt::Jump(tailrec_loop, root.arena.alloc([initial_structure]));
|
||||||
let union_layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
let union_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
let loop_param = Param {
|
let loop_param = Param {
|
||||||
symbol: current,
|
symbol: current,
|
||||||
ownership: Ownership::Borrowed,
|
ownership: Ownership::Borrowed,
|
||||||
|
|
|
@ -199,7 +199,7 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
||||||
// lazily.
|
// lazily.
|
||||||
loop {
|
loop {
|
||||||
layout = self.interner.chase_recursive_in(layout);
|
layout = self.interner.chase_recursive_in(layout);
|
||||||
match self.interner.get(layout).repr {
|
match self.interner.get_repr(layout) {
|
||||||
LayoutRepr::LambdaSet(ls) => layout = ls.representation,
|
LayoutRepr::LambdaSet(ls) => layout = ls.representation,
|
||||||
_ => return layout,
|
_ => return layout,
|
||||||
}
|
}
|
||||||
|
@ -292,7 +292,7 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
||||||
} => {
|
} => {
|
||||||
self.check_sym_layout(*cond_symbol, *cond_layout, UseKind::SwitchCond);
|
self.check_sym_layout(*cond_symbol, *cond_layout, UseKind::SwitchCond);
|
||||||
let layout = self.resolve(*cond_layout);
|
let layout = self.resolve(*cond_layout);
|
||||||
match self.interner.get(layout).repr {
|
match self.interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(_)) => {}
|
LayoutRepr::Builtin(Builtin::Int(_)) => {}
|
||||||
LayoutRepr::Builtin(Builtin::Bool) => {}
|
LayoutRepr::Builtin(Builtin::Bool) => {}
|
||||||
_ => self.problem(ProblemKind::BadSwitchConditionLayout {
|
_ => self.problem(ProblemKind::BadSwitchConditionLayout {
|
||||||
|
@ -400,7 +400,7 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
||||||
} => {
|
} => {
|
||||||
let interned_layout = self
|
let interned_layout = self
|
||||||
.interner
|
.interner
|
||||||
.insert_no_semantic(LayoutRepr::Union(tag_layout));
|
.insert_direct_no_semantic(LayoutRepr::Union(tag_layout));
|
||||||
self.check_tag_expr(interned_layout, tag_layout, tag_id, arguments);
|
self.check_tag_expr(interned_layout, tag_layout, tag_id, arguments);
|
||||||
Some(interned_layout)
|
Some(interned_layout)
|
||||||
}
|
}
|
||||||
|
@ -440,7 +440,9 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
||||||
}
|
}
|
||||||
Some(
|
Some(
|
||||||
self.interner
|
self.interner
|
||||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(*elem_layout))),
|
.insert_direct_no_semantic(LayoutRepr::Builtin(Builtin::List(
|
||||||
|
*elem_layout,
|
||||||
|
))),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Expr::EmptyArray => {
|
Expr::EmptyArray => {
|
||||||
|
@ -449,11 +451,14 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
||||||
}
|
}
|
||||||
&Expr::ExprBox { symbol } => self.with_sym_layout(symbol, |ctx, _def_line, layout| {
|
&Expr::ExprBox { symbol } => self.with_sym_layout(symbol, |ctx, _def_line, layout| {
|
||||||
let inner = layout;
|
let inner = layout;
|
||||||
Some(ctx.interner.insert_no_semantic(LayoutRepr::Boxed(inner)))
|
Some(
|
||||||
|
ctx.interner
|
||||||
|
.insert_direct_no_semantic(LayoutRepr::Boxed(inner)),
|
||||||
|
)
|
||||||
}),
|
}),
|
||||||
&Expr::ExprUnbox { symbol } => self.with_sym_layout(symbol, |ctx, def_line, layout| {
|
&Expr::ExprUnbox { symbol } => self.with_sym_layout(symbol, |ctx, def_line, layout| {
|
||||||
let layout = ctx.resolve(layout);
|
let layout = ctx.resolve(layout);
|
||||||
match ctx.interner.get(layout).repr {
|
match ctx.interner.get_repr(layout) {
|
||||||
LayoutRepr::Boxed(inner) => Some(inner),
|
LayoutRepr::Boxed(inner) => Some(inner),
|
||||||
_ => {
|
_ => {
|
||||||
ctx.problem(ProblemKind::UnboxNotABox { symbol, def_line });
|
ctx.problem(ProblemKind::UnboxNotABox { symbol, def_line });
|
||||||
|
@ -471,7 +476,7 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
||||||
} => {
|
} => {
|
||||||
let union = self
|
let union = self
|
||||||
.interner
|
.interner
|
||||||
.insert_no_semantic(LayoutRepr::Union(tag_layout));
|
.insert_direct_no_semantic(LayoutRepr::Union(tag_layout));
|
||||||
self.check_sym_layout(symbol, union, UseKind::TagReuse);
|
self.check_sym_layout(symbol, union, UseKind::TagReuse);
|
||||||
// TODO also check update arguments
|
// TODO also check update arguments
|
||||||
Some(union)
|
Some(union)
|
||||||
|
@ -494,7 +499,7 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
||||||
fn check_struct_at_index(&mut self, structure: Symbol, index: u64) -> Option<InLayout<'a>> {
|
fn check_struct_at_index(&mut self, structure: Symbol, index: u64) -> Option<InLayout<'a>> {
|
||||||
self.with_sym_layout(structure, |ctx, def_line, layout| {
|
self.with_sym_layout(structure, |ctx, def_line, layout| {
|
||||||
let layout = ctx.resolve(layout);
|
let layout = ctx.resolve(layout);
|
||||||
match ctx.interner.get(layout).repr {
|
match ctx.interner.get_repr(layout) {
|
||||||
LayoutRepr::Struct(field_layouts) => {
|
LayoutRepr::Struct(field_layouts) => {
|
||||||
if index as usize >= field_layouts.len() {
|
if index as usize >= field_layouts.len() {
|
||||||
ctx.problem(ProblemKind::StructIndexOOB {
|
ctx.problem(ProblemKind::StructIndexOOB {
|
||||||
|
@ -529,7 +534,7 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
||||||
) -> Option<InLayout<'a>> {
|
) -> Option<InLayout<'a>> {
|
||||||
let union = self
|
let union = self
|
||||||
.interner
|
.interner
|
||||||
.insert_no_semantic(LayoutRepr::Union(union_layout));
|
.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
self.with_sym_layout(structure, |ctx, def_line, _layout| {
|
self.with_sym_layout(structure, |ctx, def_line, _layout| {
|
||||||
ctx.check_sym_layout(structure, union, UseKind::TagExpr);
|
ctx.check_sym_layout(structure, union, UseKind::TagExpr);
|
||||||
|
|
||||||
|
|
|
@ -483,9 +483,9 @@ fn specialize_drops_stmt<'a, 'i>(
|
||||||
|
|
||||||
// This decremented symbol was not incremented before, perhaps the children were.
|
// This decremented symbol was not incremented before, perhaps the children were.
|
||||||
let in_layout = environment.get_symbol_layout(symbol);
|
let in_layout = environment.get_symbol_layout(symbol);
|
||||||
let runtime_layout = layout_interner.runtime_representation(*in_layout);
|
let runtime_repr = layout_interner.runtime_representation(*in_layout);
|
||||||
|
|
||||||
let updated_stmt = match runtime_layout.repr {
|
let updated_stmt = match runtime_repr {
|
||||||
// Layout has children, try to inline them.
|
// Layout has children, try to inline them.
|
||||||
LayoutRepr::Struct(field_layouts) => specialize_struct(
|
LayoutRepr::Struct(field_layouts) => specialize_struct(
|
||||||
arena,
|
arena,
|
||||||
|
|
|
@ -677,10 +677,17 @@ fn insert_refcount_operations_stmt<'v, 'a>(
|
||||||
} => {
|
} => {
|
||||||
let new_remainder = insert_refcount_operations_stmt(arena, environment, remainder);
|
let new_remainder = insert_refcount_operations_stmt(arena, environment, remainder);
|
||||||
|
|
||||||
|
let newer_remainder = consume_and_insert_dec_stmts(
|
||||||
|
arena,
|
||||||
|
environment,
|
||||||
|
environment.borrowed_usages([*symbol]),
|
||||||
|
new_remainder,
|
||||||
|
);
|
||||||
|
|
||||||
arena.alloc(Stmt::Dbg {
|
arena.alloc(Stmt::Dbg {
|
||||||
symbol: *symbol,
|
symbol: *symbol,
|
||||||
variable: *variable,
|
variable: *variable,
|
||||||
remainder: new_remainder,
|
remainder: newer_remainder,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Stmt::Join {
|
Stmt::Join {
|
||||||
|
|
|
@ -1066,7 +1066,7 @@ impl<'a> Procs<'a> {
|
||||||
let is_self_recursive = match top_level
|
let is_self_recursive = match top_level
|
||||||
.arguments
|
.arguments
|
||||||
.last()
|
.last()
|
||||||
.map(|l| layout_cache.get_in(*l).repr)
|
.map(|l| layout_cache.get_repr(*l))
|
||||||
{
|
{
|
||||||
Some(LayoutRepr::LambdaSet(lambda_set)) => lambda_set.contains(name.name()),
|
Some(LayoutRepr::LambdaSet(lambda_set)) => lambda_set.contains(name.name()),
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -3509,10 +3509,10 @@ fn specialize_proc_help<'a>(
|
||||||
|
|
||||||
combined.sort_by(|(_, layout1), (_, layout2)| {
|
combined.sort_by(|(_, layout1), (_, layout2)| {
|
||||||
let size1 = layout_cache
|
let size1 = layout_cache
|
||||||
.get_in(**layout1)
|
.get_repr(**layout1)
|
||||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||||
let size2 = layout_cache
|
let size2 = layout_cache
|
||||||
.get_in(**layout2)
|
.get_repr(**layout2)
|
||||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||||
|
|
||||||
size2.cmp(&size1)
|
size2.cmp(&size1)
|
||||||
|
@ -3557,10 +3557,10 @@ fn specialize_proc_help<'a>(
|
||||||
|
|
||||||
combined.sort_by(|(_, layout1), (_, layout2)| {
|
combined.sort_by(|(_, layout1), (_, layout2)| {
|
||||||
let size1 = layout_cache
|
let size1 = layout_cache
|
||||||
.get_in(**layout1)
|
.get_repr(**layout1)
|
||||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||||
let size2 = layout_cache
|
let size2 = layout_cache
|
||||||
.get_in(**layout2)
|
.get_repr(**layout2)
|
||||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||||
|
|
||||||
size2.cmp(&size1)
|
size2.cmp(&size1)
|
||||||
|
@ -4145,9 +4145,9 @@ pub fn with_hole<'a>(
|
||||||
|
|
||||||
IngestedFile(_, bytes, var) => {
|
IngestedFile(_, bytes, var) => {
|
||||||
let interned = layout_cache.from_var(env.arena, var, env.subs).unwrap();
|
let interned = layout_cache.from_var(env.arena, var, env.subs).unwrap();
|
||||||
let layout = layout_cache.get_in(interned);
|
let layout = layout_cache.get_repr(interned);
|
||||||
|
|
||||||
match layout.repr {
|
match layout {
|
||||||
LayoutRepr::Builtin(Builtin::List(elem_layout)) if elem_layout == Layout::U8 => {
|
LayoutRepr::Builtin(Builtin::List(elem_layout)) if elem_layout == Layout::U8 => {
|
||||||
let mut elements = Vec::with_capacity_in(bytes.len(), env.arena);
|
let mut elements = Vec::with_capacity_in(bytes.len(), env.arena);
|
||||||
for byte in bytes.iter() {
|
for byte in bytes.iter() {
|
||||||
|
@ -4422,7 +4422,32 @@ pub fn with_hole<'a>(
|
||||||
|
|
||||||
Expect { .. } => unreachable!("I think this is unreachable"),
|
Expect { .. } => unreachable!("I think this is unreachable"),
|
||||||
ExpectFx { .. } => unreachable!("I think this is unreachable"),
|
ExpectFx { .. } => unreachable!("I think this is unreachable"),
|
||||||
Dbg { .. } => unreachable!("I think this is unreachable"),
|
Dbg {
|
||||||
|
loc_condition,
|
||||||
|
loc_continuation,
|
||||||
|
variable: cond_variable,
|
||||||
|
symbol: dbg_symbol,
|
||||||
|
} => {
|
||||||
|
let rest = with_hole(
|
||||||
|
env,
|
||||||
|
loc_continuation.value,
|
||||||
|
variable,
|
||||||
|
procs,
|
||||||
|
layout_cache,
|
||||||
|
assigned,
|
||||||
|
hole,
|
||||||
|
);
|
||||||
|
|
||||||
|
compile_dbg(
|
||||||
|
env,
|
||||||
|
procs,
|
||||||
|
layout_cache,
|
||||||
|
dbg_symbol,
|
||||||
|
*loc_condition,
|
||||||
|
cond_variable,
|
||||||
|
rest,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
If {
|
If {
|
||||||
cond_var,
|
cond_var,
|
||||||
|
@ -4627,13 +4652,14 @@ pub fn with_hole<'a>(
|
||||||
Ok(elem_layout) => {
|
Ok(elem_layout) => {
|
||||||
let expr = Expr::EmptyArray;
|
let expr = Expr::EmptyArray;
|
||||||
let list_layout = layout_cache
|
let list_layout = layout_cache
|
||||||
.put_in_no_semantic(LayoutRepr::Builtin(Builtin::List(elem_layout)));
|
.put_in_direct_no_semantic(LayoutRepr::Builtin(Builtin::List(elem_layout)));
|
||||||
Stmt::Let(assigned, expr, list_layout, hole)
|
Stmt::Let(assigned, expr, list_layout, hole)
|
||||||
}
|
}
|
||||||
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
|
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
|
||||||
let expr = Expr::EmptyArray;
|
let expr = Expr::EmptyArray;
|
||||||
let list_layout = layout_cache
|
let list_layout = layout_cache.put_in_direct_no_semantic(LayoutRepr::Builtin(
|
||||||
.put_in_no_semantic(LayoutRepr::Builtin(Builtin::List(Layout::VOID)));
|
Builtin::List(Layout::VOID),
|
||||||
|
));
|
||||||
Stmt::Let(assigned, expr, list_layout, hole)
|
Stmt::Let(assigned, expr, list_layout, hole)
|
||||||
}
|
}
|
||||||
Err(LayoutProblem::Erroneous) => panic!("list element is error type"),
|
Err(LayoutProblem::Erroneous) => panic!("list element is error type"),
|
||||||
|
@ -4679,8 +4705,8 @@ pub fn with_hole<'a>(
|
||||||
elems: elements.into_bump_slice(),
|
elems: elements.into_bump_slice(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let list_layout =
|
let list_layout = layout_cache
|
||||||
layout_cache.put_in_no_semantic(LayoutRepr::Builtin(Builtin::List(elem_layout)));
|
.put_in_direct_no_semantic(LayoutRepr::Builtin(Builtin::List(elem_layout)));
|
||||||
|
|
||||||
let stmt = Stmt::Let(assigned, expr, list_layout, hole);
|
let stmt = Stmt::Let(assigned, expr, list_layout, hole);
|
||||||
|
|
||||||
|
@ -4994,7 +5020,7 @@ pub fn with_hole<'a>(
|
||||||
.from_var(env.arena, record_var, env.subs)
|
.from_var(env.arena, record_var, env.subs)
|
||||||
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
let field_layouts = match layout_cache.get_in(record_layout).repr {
|
let field_layouts = match layout_cache.get_repr(record_layout) {
|
||||||
LayoutRepr::Struct(field_layouts) => field_layouts,
|
LayoutRepr::Struct(field_layouts) => field_layouts,
|
||||||
_ => arena.alloc([record_layout]),
|
_ => arena.alloc([record_layout]),
|
||||||
};
|
};
|
||||||
|
@ -5620,6 +5646,53 @@ pub fn with_hole<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compiles a `dbg` expression.
|
||||||
|
fn compile_dbg<'a>(
|
||||||
|
env: &mut Env<'a, '_>,
|
||||||
|
procs: &mut Procs<'a>,
|
||||||
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
|
dbg_symbol: Symbol,
|
||||||
|
loc_condition: Loc<roc_can::expr::Expr>,
|
||||||
|
variable: Variable,
|
||||||
|
continuation: Stmt<'a>,
|
||||||
|
) -> Stmt<'a> {
|
||||||
|
let spec_var = env
|
||||||
|
.expectation_subs
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.fresh_unnamed_flex_var();
|
||||||
|
|
||||||
|
let dbg_stmt = Stmt::Dbg {
|
||||||
|
symbol: dbg_symbol,
|
||||||
|
variable: spec_var,
|
||||||
|
remainder: env.arena.alloc(continuation),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Now that the dbg value has been specialized, export its specialized type into the
|
||||||
|
// expectations subs.
|
||||||
|
store_specialized_expectation_lookups(env, [variable], &[spec_var]);
|
||||||
|
|
||||||
|
let symbol_is_reused = matches!(
|
||||||
|
can_reuse_symbol(env, layout_cache, procs, &loc_condition.value, variable),
|
||||||
|
ReuseSymbol::Value(_)
|
||||||
|
);
|
||||||
|
|
||||||
|
// skip evaluating the condition if it's just a symbol
|
||||||
|
if symbol_is_reused {
|
||||||
|
dbg_stmt
|
||||||
|
} else {
|
||||||
|
with_hole(
|
||||||
|
env,
|
||||||
|
loc_condition.value,
|
||||||
|
variable,
|
||||||
|
procs,
|
||||||
|
layout_cache,
|
||||||
|
dbg_symbol,
|
||||||
|
env.arena.alloc(dbg_stmt),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Compiles an access into a tuple or record.
|
/// Compiles an access into a tuple or record.
|
||||||
fn compile_struct_like_access<'a>(
|
fn compile_struct_like_access<'a>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
|
@ -5917,10 +5990,10 @@ where
|
||||||
|
|
||||||
combined.sort_by(|(_, layout1), (_, layout2)| {
|
combined.sort_by(|(_, layout1), (_, layout2)| {
|
||||||
let size1 = layout_cache
|
let size1 = layout_cache
|
||||||
.get_in(**layout1)
|
.get_repr(**layout1)
|
||||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||||
let size2 = layout_cache
|
let size2 = layout_cache
|
||||||
.get_in(**layout2)
|
.get_repr(**layout2)
|
||||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||||
|
|
||||||
size2.cmp(&size1)
|
size2.cmp(&size1)
|
||||||
|
@ -5951,10 +6024,10 @@ where
|
||||||
|
|
||||||
combined.sort_by(|(_, layout1), (_, layout2)| {
|
combined.sort_by(|(_, layout1), (_, layout2)| {
|
||||||
let size1 = layout_cache
|
let size1 = layout_cache
|
||||||
.get_in(**layout1)
|
.get_repr(**layout1)
|
||||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||||
let size2 = layout_cache
|
let size2 = layout_cache
|
||||||
.get_in(**layout2)
|
.get_repr(**layout2)
|
||||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||||
|
|
||||||
size2.cmp(&size1)
|
size2.cmp(&size1)
|
||||||
|
@ -5967,9 +6040,7 @@ where
|
||||||
|
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
LayoutRepr::struct_(field_layouts),
|
LayoutRepr::struct_(field_layouts),
|
||||||
layout_cache
|
layout_cache.get_repr(lambda_set.runtime_representation())
|
||||||
.get_in(lambda_set.runtime_representation())
|
|
||||||
.repr
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let expr = Expr::Struct(symbols);
|
let expr = Expr::Struct(symbols);
|
||||||
|
@ -6170,7 +6241,7 @@ fn convert_tag_union<'a>(
|
||||||
layout_cache.from_var(env.arena, variant_var, env.subs),
|
layout_cache.from_var(env.arena, variant_var, env.subs),
|
||||||
"Wrapped"
|
"Wrapped"
|
||||||
);
|
);
|
||||||
let union_layout = match layout_cache.interner.chase_recursive(variant_layout).repr {
|
let union_layout = match layout_cache.interner.chase_recursive(variant_layout) {
|
||||||
LayoutRepr::Union(ul) => ul,
|
LayoutRepr::Union(ul) => ul,
|
||||||
other => internal_error!(
|
other => internal_error!(
|
||||||
"unexpected layout {:?} for {:?}",
|
"unexpected layout {:?} for {:?}",
|
||||||
|
@ -6301,7 +6372,8 @@ fn convert_tag_union<'a>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let union_layout = layout_cache.put_in_no_semantic(LayoutRepr::Union(union_layout));
|
let union_layout =
|
||||||
|
layout_cache.put_in_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
|
|
||||||
let stmt = Stmt::Let(assigned, tag, union_layout, hole);
|
let stmt = Stmt::Let(assigned, tag, union_layout, hole);
|
||||||
let iter = field_symbols_temp
|
let iter = field_symbols_temp
|
||||||
|
@ -6440,7 +6512,7 @@ fn sorted_field_symbols<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let alignment = layout_cache
|
let alignment = layout_cache
|
||||||
.get_in(layout)
|
.get_repr(layout)
|
||||||
.alignment_bytes(&layout_cache.interner, env.target_info);
|
.alignment_bytes(&layout_cache.interner, env.target_info);
|
||||||
|
|
||||||
let symbol = possible_reuse_symbol_or_specialize(env, procs, layout_cache, &arg.value, var);
|
let symbol = possible_reuse_symbol_or_specialize(env, procs, layout_cache, &arg.value, var);
|
||||||
|
@ -6824,41 +6896,15 @@ pub fn from_can<'a>(
|
||||||
} => {
|
} => {
|
||||||
let rest = from_can(env, variable, loc_continuation.value, procs, layout_cache);
|
let rest = from_can(env, variable, loc_continuation.value, procs, layout_cache);
|
||||||
|
|
||||||
let spec_var = env
|
compile_dbg(
|
||||||
.expectation_subs
|
env,
|
||||||
.as_mut()
|
procs,
|
||||||
.unwrap()
|
layout_cache,
|
||||||
.fresh_unnamed_flex_var();
|
dbg_symbol,
|
||||||
|
*loc_condition,
|
||||||
let dbg_stmt = Stmt::Dbg {
|
variable,
|
||||||
symbol: dbg_symbol,
|
rest,
|
||||||
variable: spec_var,
|
)
|
||||||
remainder: env.arena.alloc(rest),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Now that the dbg value has been specialized, export its specialized type into the
|
|
||||||
// expectations subs.
|
|
||||||
store_specialized_expectation_lookups(env, [variable], &[spec_var]);
|
|
||||||
|
|
||||||
let symbol_is_reused = matches!(
|
|
||||||
can_reuse_symbol(env, layout_cache, procs, &loc_condition.value, variable),
|
|
||||||
ReuseSymbol::Value(_)
|
|
||||||
);
|
|
||||||
|
|
||||||
// skip evaluating the condition if it's just a symbol
|
|
||||||
if symbol_is_reused {
|
|
||||||
dbg_stmt
|
|
||||||
} else {
|
|
||||||
with_hole(
|
|
||||||
env,
|
|
||||||
loc_condition.value,
|
|
||||||
variable,
|
|
||||||
procs,
|
|
||||||
layout_cache,
|
|
||||||
dbg_symbol,
|
|
||||||
env.arena.alloc(dbg_stmt),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LetRec(defs, cont, _cycle_mark) => {
|
LetRec(defs, cont, _cycle_mark) => {
|
||||||
|
@ -7887,7 +7933,7 @@ fn specialize_symbol<'a>(
|
||||||
let layout = match raw {
|
let layout = match raw {
|
||||||
RawFunctionLayout::ZeroArgumentThunk(layout) => layout,
|
RawFunctionLayout::ZeroArgumentThunk(layout) => layout,
|
||||||
RawFunctionLayout::Function(_, lambda_set, _) => layout_cache
|
RawFunctionLayout::Function(_, lambda_set, _) => layout_cache
|
||||||
.put_in_no_semantic(LayoutRepr::LambdaSet(lambda_set)),
|
.put_in_direct_no_semantic(LayoutRepr::LambdaSet(lambda_set)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let raw = RawFunctionLayout::ZeroArgumentThunk(layout);
|
let raw = RawFunctionLayout::ZeroArgumentThunk(layout);
|
||||||
|
@ -9764,7 +9810,7 @@ where
|
||||||
($tag_id:expr, $layout:expr, $union_layout:expr, $field_layouts: expr) => {{
|
($tag_id:expr, $layout:expr, $union_layout:expr, $field_layouts: expr) => {{
|
||||||
if $field_layouts.iter().any(|l| {
|
if $field_layouts.iter().any(|l| {
|
||||||
layout_interner
|
layout_interner
|
||||||
.get(*l)
|
.get_repr(*l)
|
||||||
.has_varying_stack_size(layout_interner, arena)
|
.has_varying_stack_size(layout_interner, arena)
|
||||||
}) {
|
}) {
|
||||||
let procs = generate_glue_procs_for_tag_fields(
|
let procs = generate_glue_procs_for_tag_fields(
|
||||||
|
@ -9789,7 +9835,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(layout) = stack.pop() {
|
while let Some(layout) = stack.pop() {
|
||||||
match layout.repr {
|
match layout.repr(layout_interner) {
|
||||||
LayoutRepr::Builtin(builtin) => match builtin {
|
LayoutRepr::Builtin(builtin) => match builtin {
|
||||||
Builtin::Int(_)
|
Builtin::Int(_)
|
||||||
| Builtin::Float(_)
|
| Builtin::Float(_)
|
||||||
|
@ -9801,7 +9847,7 @@ where
|
||||||
LayoutRepr::Struct(field_layouts) => {
|
LayoutRepr::Struct(field_layouts) => {
|
||||||
if field_layouts.iter().any(|l| {
|
if field_layouts.iter().any(|l| {
|
||||||
layout_interner
|
layout_interner
|
||||||
.get(*l)
|
.get_repr(*l)
|
||||||
.has_varying_stack_size(layout_interner, arena)
|
.has_varying_stack_size(layout_interner, arena)
|
||||||
}) {
|
}) {
|
||||||
let procs = generate_glue_procs_for_struct_fields(
|
let procs = generate_glue_procs_for_struct_fields(
|
||||||
|
@ -9892,11 +9938,11 @@ where
|
||||||
{
|
{
|
||||||
let interned_unboxed_struct_layout = layout_interner.insert(*unboxed_struct_layout);
|
let interned_unboxed_struct_layout = layout_interner.insert(*unboxed_struct_layout);
|
||||||
let boxed_struct_layout =
|
let boxed_struct_layout =
|
||||||
Layout::no_semantic(LayoutRepr::Boxed(interned_unboxed_struct_layout));
|
Layout::no_semantic(LayoutRepr::Boxed(interned_unboxed_struct_layout).direct());
|
||||||
let boxed_struct_layout = layout_interner.insert(boxed_struct_layout);
|
let boxed_struct_layout = layout_interner.insert(boxed_struct_layout);
|
||||||
let mut answer = bumpalo::collections::Vec::with_capacity_in(field_layouts.len(), arena);
|
let mut answer = bumpalo::collections::Vec::with_capacity_in(field_layouts.len(), arena);
|
||||||
|
|
||||||
let field_layouts = match layout_interner.get(interned_unboxed_struct_layout).repr {
|
let field_layouts = match layout_interner.get_repr(interned_unboxed_struct_layout) {
|
||||||
LayoutRepr::Struct(field_layouts) => field_layouts,
|
LayoutRepr::Struct(field_layouts) => field_layouts,
|
||||||
other => {
|
other => {
|
||||||
unreachable!(
|
unreachable!(
|
||||||
|
@ -10003,7 +10049,7 @@ where
|
||||||
I: LayoutInterner<'a>,
|
I: LayoutInterner<'a>,
|
||||||
{
|
{
|
||||||
let interned = layout_interner.insert(*unboxed_struct_layout);
|
let interned = layout_interner.insert(*unboxed_struct_layout);
|
||||||
let boxed_struct_layout = Layout::no_semantic(LayoutRepr::Boxed(interned));
|
let boxed_struct_layout = Layout::no_semantic(LayoutRepr::Boxed(interned).direct());
|
||||||
let boxed_struct_layout = layout_interner.insert(boxed_struct_layout);
|
let boxed_struct_layout = layout_interner.insert(boxed_struct_layout);
|
||||||
let mut answer = bumpalo::collections::Vec::with_capacity_in(field_layouts.len(), arena);
|
let mut answer = bumpalo::collections::Vec::with_capacity_in(field_layouts.len(), arena);
|
||||||
|
|
||||||
|
|
|
@ -1014,7 +1014,7 @@ fn to_relevant_branch_help<'a>(
|
||||||
// the test matches the constructor of this pattern
|
// the test matches the constructor of this pattern
|
||||||
match layout {
|
match layout {
|
||||||
UnionLayout::NonRecursive([[arg]])
|
UnionLayout::NonRecursive([[arg]])
|
||||||
if matches!(interner.get(*arg).repr, LayoutRepr::Struct([_],)) =>
|
if matches!(interner.get_repr(*arg), LayoutRepr::Struct([_],)) =>
|
||||||
{
|
{
|
||||||
// a one-element record equivalent
|
// a one-element record equivalent
|
||||||
// Theory: Unbox doesn't have any value for us
|
// Theory: Unbox doesn't have any value for us
|
||||||
|
@ -1573,7 +1573,7 @@ fn path_to_expr_help<'a>(
|
||||||
PathInstruction::TagIndex { index, tag_id } => {
|
PathInstruction::TagIndex { index, tag_id } => {
|
||||||
let index = *index;
|
let index = *index;
|
||||||
|
|
||||||
match layout_interner.chase_recursive(layout).repr {
|
match layout_interner.chase_recursive(layout) {
|
||||||
LayoutRepr::Union(union_layout) => {
|
LayoutRepr::Union(union_layout) => {
|
||||||
let inner_expr = Expr::UnionAtIndex {
|
let inner_expr = Expr::UnionAtIndex {
|
||||||
tag_id: *tag_id,
|
tag_id: *tag_id,
|
||||||
|
@ -1626,7 +1626,7 @@ fn path_to_expr_help<'a>(
|
||||||
PathInstruction::ListIndex { index } => {
|
PathInstruction::ListIndex { index } => {
|
||||||
let list_sym = symbol;
|
let list_sym = symbol;
|
||||||
|
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::List(elem_layout)) => {
|
LayoutRepr::Builtin(Builtin::List(elem_layout)) => {
|
||||||
let (index_sym, new_stores) = build_list_index_probe(env, list_sym, index);
|
let (index_sym, new_stores) = build_list_index_probe(env, list_sym, index);
|
||||||
|
|
||||||
|
@ -1673,7 +1673,7 @@ fn test_to_comparison<'a>(
|
||||||
// (e.g. record pattern guard matches)
|
// (e.g. record pattern guard matches)
|
||||||
debug_assert!(union.alternatives.len() > 1);
|
debug_assert!(union.alternatives.len() > 1);
|
||||||
|
|
||||||
match layout_interner.chase_recursive(test_layout).repr {
|
match layout_interner.chase_recursive(test_layout) {
|
||||||
LayoutRepr::Union(union_layout) => {
|
LayoutRepr::Union(union_layout) => {
|
||||||
let lhs = Expr::Literal(Literal::Int((tag_id as i128).to_ne_bytes()));
|
let lhs = Expr::Literal(Literal::Int((tag_id as i128).to_ne_bytes()));
|
||||||
|
|
||||||
|
@ -1763,7 +1763,7 @@ fn test_to_comparison<'a>(
|
||||||
let list_layout = test_layout;
|
let list_layout = test_layout;
|
||||||
let list_sym = rhs_symbol;
|
let list_sym = rhs_symbol;
|
||||||
|
|
||||||
match layout_interner.get(list_layout).repr {
|
match layout_interner.get_repr(list_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::List(_elem_layout)) => {
|
LayoutRepr::Builtin(Builtin::List(_elem_layout)) => {
|
||||||
let real_len_expr = Expr::Call(Call {
|
let real_len_expr = Expr::Call(Call {
|
||||||
call_type: CallType::LowLevel {
|
call_type: CallType::LowLevel {
|
||||||
|
@ -2310,7 +2310,7 @@ fn decide_to_branching<'a>(
|
||||||
// We have learned more about the exact layout of the cond (based on the path)
|
// We have learned more about the exact layout of the cond (based on the path)
|
||||||
// but tests are still relative to the original cond symbol
|
// but tests are still relative to the original cond symbol
|
||||||
let inner_cond_layout_raw = layout_cache.interner.chase_recursive(inner_cond_layout);
|
let inner_cond_layout_raw = layout_cache.interner.chase_recursive(inner_cond_layout);
|
||||||
let mut switch = if let LayoutRepr::Union(union_layout) = inner_cond_layout_raw.repr {
|
let mut switch = if let LayoutRepr::Union(union_layout) = inner_cond_layout_raw {
|
||||||
let tag_id_symbol = env.unique_symbol();
|
let tag_id_symbol = env.unique_symbol();
|
||||||
|
|
||||||
let temp = Stmt::Switch {
|
let temp = Stmt::Switch {
|
||||||
|
@ -2332,7 +2332,7 @@ fn decide_to_branching<'a>(
|
||||||
union_layout.tag_id_layout(),
|
union_layout.tag_id_layout(),
|
||||||
env.arena.alloc(temp),
|
env.arena.alloc(temp),
|
||||||
)
|
)
|
||||||
} else if let LayoutRepr::Builtin(Builtin::List(_)) = inner_cond_layout_raw.repr {
|
} else if let LayoutRepr::Builtin(Builtin::List(_)) = inner_cond_layout_raw {
|
||||||
let len_symbol = env.unique_symbol();
|
let len_symbol = env.unique_symbol();
|
||||||
|
|
||||||
let switch = Stmt::Switch {
|
let switch = Stmt::Switch {
|
||||||
|
|
|
@ -83,7 +83,7 @@ pub fn make_num_literal<'a>(
|
||||||
num_str: &str,
|
num_str: &str,
|
||||||
num_value: IntOrFloatValue,
|
num_value: IntOrFloatValue,
|
||||||
) -> NumLiteral {
|
) -> NumLiteral {
|
||||||
match interner.get(layout).repr {
|
match interner.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Int(width)) => match num_value {
|
LayoutRepr::Builtin(Builtin::Int(width)) => match num_value {
|
||||||
IntOrFloatValue::Int(IntValue::I128(n)) => NumLiteral::Int(n, width),
|
IntOrFloatValue::Int(IntValue::I128(n)) => NumLiteral::Int(n, width),
|
||||||
IntOrFloatValue::Int(IntValue::U128(n)) => NumLiteral::U128(n),
|
IntOrFloatValue::Int(IntValue::U128(n)) => NumLiteral::U128(n),
|
||||||
|
|
|
@ -344,7 +344,7 @@ fn from_can_pattern_help<'a>(
|
||||||
StrLiteral(v) => Ok(Pattern::StrLiteral(v.clone())),
|
StrLiteral(v) => Ok(Pattern::StrLiteral(v.clone())),
|
||||||
SingleQuote(var, _, c, _) => {
|
SingleQuote(var, _, c, _) => {
|
||||||
let layout = layout_cache.from_var(env.arena, *var, env.subs);
|
let layout = layout_cache.from_var(env.arena, *var, env.subs);
|
||||||
match layout.map(|l| layout_cache.get_in(l).repr) {
|
match layout.map(|l| layout_cache.get_repr(l)) {
|
||||||
Ok(LayoutRepr::Builtin(Builtin::Int(width))) => {
|
Ok(LayoutRepr::Builtin(Builtin::Int(width))) => {
|
||||||
Ok(Pattern::IntLiteral((*c as i128).to_ne_bytes(), width))
|
Ok(Pattern::IntLiteral((*c as i128).to_ne_bytes(), width))
|
||||||
}
|
}
|
||||||
|
@ -583,12 +583,11 @@ fn from_can_pattern_help<'a>(
|
||||||
// problems down the line because we hash layouts and an unrolled
|
// problems down the line because we hash layouts and an unrolled
|
||||||
// version is not the same as the minimal version.
|
// version is not the same as the minimal version.
|
||||||
let whole_var_layout = layout_cache.from_var(env.arena, *whole_var, env.subs);
|
let whole_var_layout = layout_cache.from_var(env.arena, *whole_var, env.subs);
|
||||||
let layout = match whole_var_layout
|
let layout =
|
||||||
.map(|l| layout_cache.interner.chase_recursive(l).repr)
|
match whole_var_layout.map(|l| layout_cache.interner.chase_recursive(l)) {
|
||||||
{
|
Ok(LayoutRepr::Union(ul)) => ul,
|
||||||
Ok(LayoutRepr::Union(ul)) => ul,
|
_ => internal_error!(),
|
||||||
_ => internal_error!(),
|
};
|
||||||
};
|
|
||||||
|
|
||||||
use WrappedVariant::*;
|
use WrappedVariant::*;
|
||||||
match variant {
|
match variant {
|
||||||
|
@ -1207,8 +1206,8 @@ fn store_pattern_help<'a>(
|
||||||
let mut fields = Vec::with_capacity_in(arguments.len(), env.arena);
|
let mut fields = Vec::with_capacity_in(arguments.len(), env.arena);
|
||||||
fields.extend(arguments.iter().map(|x| x.1));
|
fields.extend(arguments.iter().map(|x| x.1));
|
||||||
|
|
||||||
let layout =
|
let layout = layout_cache
|
||||||
layout_cache.put_in_no_semantic(LayoutRepr::struct_(fields.into_bump_slice()));
|
.put_in_direct_no_semantic(LayoutRepr::struct_(fields.into_bump_slice()));
|
||||||
|
|
||||||
return store_newtype_pattern(
|
return store_newtype_pattern(
|
||||||
env,
|
env,
|
||||||
|
@ -1552,9 +1551,9 @@ fn store_tag_pattern<'a>(
|
||||||
for (index, (argument, arg_layout)) in arguments.iter().enumerate().rev() {
|
for (index, (argument, arg_layout)) in arguments.iter().enumerate().rev() {
|
||||||
let mut arg_layout = *arg_layout;
|
let mut arg_layout = *arg_layout;
|
||||||
|
|
||||||
if let LayoutRepr::RecursivePointer(_) = layout_cache.get_in(arg_layout).repr {
|
if let LayoutRepr::RecursivePointer(_) = layout_cache.get_repr(arg_layout) {
|
||||||
// TODO(recursive-layouts): fix after disjoint rec ptrs
|
// TODO(recursive-layouts): fix after disjoint rec ptrs
|
||||||
arg_layout = layout_cache.put_in_no_semantic(LayoutRepr::Union(union_layout));
|
arg_layout = layout_cache.put_in_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||||
}
|
}
|
||||||
|
|
||||||
let load = Expr::UnionAtIndex {
|
let load = Expr::UnionAtIndex {
|
||||||
|
@ -1630,7 +1629,7 @@ fn store_newtype_pattern<'a>(
|
||||||
for (index, (argument, arg_layout)) in arguments.iter().enumerate().rev() {
|
for (index, (argument, arg_layout)) in arguments.iter().enumerate().rev() {
|
||||||
let mut arg_layout = *arg_layout;
|
let mut arg_layout = *arg_layout;
|
||||||
|
|
||||||
if let LayoutRepr::RecursivePointer(_) = layout_cache.get_in(arg_layout).repr {
|
if let LayoutRepr::RecursivePointer(_) = layout_cache.get_repr(arg_layout) {
|
||||||
arg_layout = layout;
|
arg_layout = layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -328,12 +328,15 @@ impl<'a> LayoutCache<'a> {
|
||||||
pub fn get_in(&self, interned: InLayout<'a>) -> Layout<'a> {
|
pub fn get_in(&self, interned: InLayout<'a>) -> Layout<'a> {
|
||||||
self.interner.get(interned)
|
self.interner.get(interned)
|
||||||
}
|
}
|
||||||
|
pub fn get_repr(&self, interned: InLayout<'a>) -> LayoutRepr<'a> {
|
||||||
|
self.interner.get_repr(interned)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn put_in(&mut self, layout: Layout<'a>) -> InLayout<'a> {
|
pub fn put_in(&mut self, layout: Layout<'a>) -> InLayout<'a> {
|
||||||
self.interner.insert(layout)
|
self.interner.insert(layout)
|
||||||
}
|
}
|
||||||
pub fn put_in_no_semantic(&mut self, repr: LayoutRepr<'a>) -> InLayout<'a> {
|
pub(crate) fn put_in_direct_no_semantic(&mut self, repr: LayoutRepr<'a>) -> InLayout<'a> {
|
||||||
self.interner.insert_no_semantic(repr)
|
self.interner.insert_direct_no_semantic(repr)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
|
@ -656,10 +659,16 @@ impl<'a> RawFunctionLayout<'a> {
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub struct Layout<'a> {
|
pub struct Layout<'a> {
|
||||||
pub repr: LayoutRepr<'a>,
|
repr: LayoutWrapper<'a>,
|
||||||
semantic: SemanticRepr<'a>,
|
semantic: SemanticRepr<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
|
pub(crate) enum LayoutWrapper<'a> {
|
||||||
|
Direct(LayoutRepr<'a>),
|
||||||
|
Newtype(InLayout<'a>),
|
||||||
|
}
|
||||||
|
|
||||||
/// Types for code gen must be monomorphic. No type variables allowed!
|
/// Types for code gen must be monomorphic. No type variables allowed!
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub enum LayoutRepr<'a> {
|
pub enum LayoutRepr<'a> {
|
||||||
|
@ -873,8 +882,8 @@ impl<'a> UnionLayout<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO(recursive-layouts): simplify after we have disjoint recursive pointers
|
// TODO(recursive-layouts): simplify after we have disjoint recursive pointers
|
||||||
if let LayoutRepr::RecursivePointer(_) = interner.get(result).repr {
|
if let LayoutRepr::RecursivePointer(_) = interner.get_repr(result) {
|
||||||
interner.insert_no_semantic(LayoutRepr::Union(self))
|
interner.insert_direct_no_semantic(LayoutRepr::Union(self))
|
||||||
} else {
|
} else {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
@ -1417,7 +1426,7 @@ impl<'a> LambdaSet<'a> {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let repr = self.representation;
|
let repr = self.representation;
|
||||||
match interner.get(repr).repr {
|
match interner.get_repr(repr) {
|
||||||
LayoutRepr::Struct(&[]) => None,
|
LayoutRepr::Struct(&[]) => None,
|
||||||
_ => Some(repr),
|
_ => Some(repr),
|
||||||
}
|
}
|
||||||
|
@ -1533,7 +1542,7 @@ impl<'a> LambdaSet<'a> {
|
||||||
|
|
||||||
let repr_layout = interner.chase_recursive(self.representation);
|
let repr_layout = interner.chase_recursive(self.representation);
|
||||||
|
|
||||||
match repr_layout.repr {
|
match repr_layout {
|
||||||
LayoutRepr::Union(union) => {
|
LayoutRepr::Union(union) => {
|
||||||
// here we rely on the fact that a union in a closure would be stored in a one-element record.
|
// here we rely on the fact that a union in a closure would be stored in a one-element record.
|
||||||
// a closure representation that is itself union must be a of the shape `Closure1 ... | Closure2 ...`
|
// a closure representation that is itself union must be a of the shape `Closure1 ... | Closure2 ...`
|
||||||
|
@ -1660,9 +1669,9 @@ impl<'a> LambdaSet<'a> {
|
||||||
|
|
||||||
let repr_layout = interner.chase_recursive(self.representation);
|
let repr_layout = interner.chase_recursive(self.representation);
|
||||||
|
|
||||||
match repr_layout.repr {
|
match repr_layout {
|
||||||
LayoutRepr::Union(union_layout) => {
|
LayoutRepr::Union(union_layout) => {
|
||||||
if repr_layout == Layout::VOID_NAKED {
|
if repr_layout == Layout::VOID_NAKED.repr(interner) {
|
||||||
debug_assert!(self.set.is_empty());
|
debug_assert!(self.set.is_empty());
|
||||||
return ClosureCallOptions::Void;
|
return ClosureCallOptions::Void;
|
||||||
}
|
}
|
||||||
|
@ -1747,7 +1756,7 @@ impl<'a> LambdaSet<'a> {
|
||||||
Cacheable(result, criteria)
|
Cacheable(result, criteria)
|
||||||
});
|
});
|
||||||
|
|
||||||
match result.map(|l| env.cache.interner.chase_recursive(l).repr) {
|
match result.map(|l| env.cache.interner.chase_recursive(l)) {
|
||||||
Ok(LayoutRepr::LambdaSet(lambda_set)) => Cacheable(Ok(lambda_set), criteria),
|
Ok(LayoutRepr::LambdaSet(lambda_set)) => Cacheable(Ok(lambda_set), criteria),
|
||||||
Err(err) => Cacheable(Err(err), criteria),
|
Err(err) => Cacheable(Err(err), criteria),
|
||||||
Ok(layout) => internal_error!("other layout found for lambda set: {:?}", layout),
|
Ok(layout) => internal_error!("other layout found for lambda set: {:?}", layout),
|
||||||
|
@ -1923,7 +1932,7 @@ impl<'a> LambdaSet<'a> {
|
||||||
I: LayoutInterner<'a>,
|
I: LayoutInterner<'a>,
|
||||||
{
|
{
|
||||||
interner
|
interner
|
||||||
.get(self.representation)
|
.get_repr(self.representation)
|
||||||
.stack_size(interner, target_info)
|
.stack_size(interner, target_info)
|
||||||
}
|
}
|
||||||
pub fn contains_refcounted<I>(&self, interner: &I) -> bool
|
pub fn contains_refcounted<I>(&self, interner: &I) -> bool
|
||||||
|
@ -1931,14 +1940,16 @@ impl<'a> LambdaSet<'a> {
|
||||||
I: LayoutInterner<'a>,
|
I: LayoutInterner<'a>,
|
||||||
{
|
{
|
||||||
interner
|
interner
|
||||||
.get(self.representation)
|
.get_repr(self.representation)
|
||||||
.contains_refcounted(interner)
|
.contains_refcounted(interner)
|
||||||
}
|
}
|
||||||
pub fn safe_to_memcpy<I>(&self, interner: &I) -> bool
|
pub fn safe_to_memcpy<I>(&self, interner: &I) -> bool
|
||||||
where
|
where
|
||||||
I: LayoutInterner<'a>,
|
I: LayoutInterner<'a>,
|
||||||
{
|
{
|
||||||
interner.get(self.representation).safe_to_memcpy(interner)
|
interner
|
||||||
|
.get_repr(self.representation)
|
||||||
|
.safe_to_memcpy(interner)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alignment_bytes<I>(&self, interner: &I, target_info: TargetInfo) -> u32
|
pub fn alignment_bytes<I>(&self, interner: &I, target_info: TargetInfo) -> u32
|
||||||
|
@ -1946,7 +1957,7 @@ impl<'a> LambdaSet<'a> {
|
||||||
I: LayoutInterner<'a>,
|
I: LayoutInterner<'a>,
|
||||||
{
|
{
|
||||||
interner
|
interner
|
||||||
.get(self.representation)
|
.get_repr(self.representation)
|
||||||
.alignment_bytes(interner, target_info)
|
.alignment_bytes(interner, target_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2125,7 +2136,7 @@ pub enum Builtin<'a> {
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! list_element_layout {
|
macro_rules! list_element_layout {
|
||||||
($interner:expr, $list_layout:expr) => {
|
($interner:expr, $list_layout:expr) => {
|
||||||
match $interner.get($list_layout).repr {
|
match $interner.get_repr($list_layout) {
|
||||||
LayoutRepr::Builtin(Builtin::List(list_layout)) => list_layout,
|
LayoutRepr::Builtin(Builtin::List(list_layout)) => list_layout,
|
||||||
_ => internal_error!("invalid list layout"),
|
_ => internal_error!("invalid list layout"),
|
||||||
}
|
}
|
||||||
|
@ -2326,19 +2337,30 @@ pub fn is_any_float_range(subs: &Subs, var: Variable) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Layout<'a> {
|
impl<'a> Layout<'a> {
|
||||||
pub const fn new(repr: LayoutRepr<'a>, semantic: SemanticRepr<'a>) -> Self {
|
pub(crate) const fn new(repr: LayoutWrapper<'a>, semantic: SemanticRepr<'a>) -> Self {
|
||||||
Self { repr, semantic }
|
Self { repr, semantic }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn no_semantic(repr: LayoutRepr<'a>) -> Self {
|
pub(crate) const fn no_semantic(repr: LayoutWrapper<'a>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
repr,
|
repr,
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn semantic(&self) -> SemanticRepr<'a> {
|
pub(crate) fn repr<I>(&self, interner: &I) -> LayoutRepr<'a>
|
||||||
self.semantic
|
where
|
||||||
|
I: LayoutInterner<'a>,
|
||||||
|
{
|
||||||
|
let mut lay = *self;
|
||||||
|
loop {
|
||||||
|
match lay.repr {
|
||||||
|
LayoutWrapper::Direct(repr) => return repr,
|
||||||
|
LayoutWrapper::Newtype(real) => {
|
||||||
|
lay = interner.get(real);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_help<'b>(
|
fn new_help<'b>(
|
||||||
|
@ -2457,7 +2479,7 @@ impl<'a> Layout<'a> {
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
for layout in tag.iter() {
|
for layout in tag.iter() {
|
||||||
let (stack_size, alignment) = interner
|
let (stack_size, alignment) = interner
|
||||||
.get(*layout)
|
.get_repr(*layout)
|
||||||
.stack_size_and_alignment(interner, target_info);
|
.stack_size_and_alignment(interner, target_info);
|
||||||
total += stack_size;
|
total += stack_size;
|
||||||
data_align = data_align.max(alignment);
|
data_align = data_align.max(alignment);
|
||||||
|
@ -2476,7 +2498,7 @@ impl<'a> Layout<'a> {
|
||||||
I: LayoutInterner<'a>,
|
I: LayoutInterner<'a>,
|
||||||
{
|
{
|
||||||
use LayoutRepr::*;
|
use LayoutRepr::*;
|
||||||
match self.repr {
|
match self.repr(interner) {
|
||||||
LambdaSet(lambda_set) => interner.get(lambda_set.runtime_representation()),
|
LambdaSet(lambda_set) => interner.get(lambda_set.runtime_representation()),
|
||||||
_ => *self,
|
_ => *self,
|
||||||
}
|
}
|
||||||
|
@ -2487,21 +2509,13 @@ impl<'a> Layout<'a> {
|
||||||
I: LayoutInterner<'a>,
|
I: LayoutInterner<'a>,
|
||||||
{
|
{
|
||||||
use LayoutRepr::*;
|
use LayoutRepr::*;
|
||||||
match interner.get(layout).repr {
|
match interner.get_repr(layout) {
|
||||||
LambdaSet(lambda_set) => lambda_set.runtime_representation(),
|
LambdaSet(lambda_set) => lambda_set.runtime_representation(),
|
||||||
_ => layout,
|
_ => layout,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> std::ops::Deref for Layout<'a> {
|
|
||||||
type Target = LayoutRepr<'a>;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.repr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> LayoutRepr<'a> {
|
impl<'a> LayoutRepr<'a> {
|
||||||
pub const UNIT: Self = LayoutRepr::struct_(&[]);
|
pub const UNIT: Self = LayoutRepr::struct_(&[]);
|
||||||
pub const BOOL: Self = LayoutRepr::Builtin(Builtin::Bool);
|
pub const BOOL: Self = LayoutRepr::Builtin(Builtin::Bool);
|
||||||
|
@ -2525,6 +2539,10 @@ impl<'a> LayoutRepr<'a> {
|
||||||
Self::Struct(field_layouts)
|
Self::Struct(field_layouts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) const fn direct(self) -> LayoutWrapper<'a> {
|
||||||
|
LayoutWrapper::Direct(self)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn safe_to_memcpy<I>(&self, interner: &I) -> bool
|
pub fn safe_to_memcpy<I>(&self, interner: &I) -> bool
|
||||||
where
|
where
|
||||||
I: LayoutInterner<'a>,
|
I: LayoutInterner<'a>,
|
||||||
|
@ -2535,7 +2553,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
Builtin(builtin) => builtin.safe_to_memcpy(),
|
Builtin(builtin) => builtin.safe_to_memcpy(),
|
||||||
Struct(field_layouts) => field_layouts
|
Struct(field_layouts) => field_layouts
|
||||||
.iter()
|
.iter()
|
||||||
.all(|field_layout| interner.get(*field_layout).safe_to_memcpy(interner)),
|
.all(|field_layout| interner.get_repr(*field_layout).safe_to_memcpy(interner)),
|
||||||
Union(variant) => {
|
Union(variant) => {
|
||||||
use UnionLayout::*;
|
use UnionLayout::*;
|
||||||
|
|
||||||
|
@ -2543,7 +2561,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
NonRecursive(tags) => tags.iter().all(|tag_layout| {
|
NonRecursive(tags) => tags.iter().all(|tag_layout| {
|
||||||
tag_layout
|
tag_layout
|
||||||
.iter()
|
.iter()
|
||||||
.all(|field| interner.get(*field).safe_to_memcpy(interner))
|
.all(|field| interner.get_repr(*field).safe_to_memcpy(interner))
|
||||||
}),
|
}),
|
||||||
Recursive(_)
|
Recursive(_)
|
||||||
| NullableWrapped { .. }
|
| NullableWrapped { .. }
|
||||||
|
@ -2555,7 +2573,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LambdaSet(lambda_set) => interner
|
LambdaSet(lambda_set) => interner
|
||||||
.get(lambda_set.runtime_representation())
|
.get_repr(lambda_set.runtime_representation())
|
||||||
.safe_to_memcpy(interner),
|
.safe_to_memcpy(interner),
|
||||||
Boxed(_) | RecursivePointer(_) => {
|
Boxed(_) | RecursivePointer(_) => {
|
||||||
// We cannot memcpy pointers, because then we would have the same pointer in multiple places!
|
// We cannot memcpy pointers, because then we would have the same pointer in multiple places!
|
||||||
|
@ -2592,7 +2610,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
}
|
}
|
||||||
LayoutRepr::Union(UnionLayout::NonRecursive(_)) => true,
|
LayoutRepr::Union(UnionLayout::NonRecursive(_)) => true,
|
||||||
LayoutRepr::LambdaSet(lambda_set) => interner
|
LayoutRepr::LambdaSet(lambda_set) => interner
|
||||||
.get(lambda_set.runtime_representation())
|
.get_repr(lambda_set.runtime_representation())
|
||||||
.is_passed_by_reference(interner, target_info),
|
.is_passed_by_reference(interner, target_info),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -2633,7 +2651,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
|
|
||||||
for field_layout in *field_layouts {
|
for field_layout in *field_layouts {
|
||||||
sum += interner
|
sum += interner
|
||||||
.get(*field_layout)
|
.get_repr(*field_layout)
|
||||||
.stack_size(interner, target_info);
|
.stack_size(interner, target_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2641,7 +2659,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
}
|
}
|
||||||
Union(variant) => variant.stack_size_without_alignment(interner, target_info),
|
Union(variant) => variant.stack_size_without_alignment(interner, target_info),
|
||||||
LambdaSet(lambda_set) => interner
|
LambdaSet(lambda_set) => interner
|
||||||
.get(lambda_set.runtime_representation())
|
.get_repr(lambda_set.runtime_representation())
|
||||||
.stack_size_without_alignment(interner, target_info),
|
.stack_size_without_alignment(interner, target_info),
|
||||||
RecursivePointer(_) => target_info.ptr_width() as u32,
|
RecursivePointer(_) => target_info.ptr_width() as u32,
|
||||||
Boxed(_) => target_info.ptr_width() as u32,
|
Boxed(_) => target_info.ptr_width() as u32,
|
||||||
|
@ -2656,7 +2674,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
match self {
|
match self {
|
||||||
Struct(field_layouts) => field_layouts
|
Struct(field_layouts) => field_layouts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| interner.get(*x).alignment_bytes(interner, target_info))
|
.map(|x| interner.get_repr(*x).alignment_bytes(interner, target_info))
|
||||||
.max()
|
.max()
|
||||||
.unwrap_or(0),
|
.unwrap_or(0),
|
||||||
|
|
||||||
|
@ -2669,7 +2687,9 @@ impl<'a> LayoutRepr<'a> {
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|layouts| {
|
.flat_map(|layouts| {
|
||||||
layouts.iter().map(|layout| {
|
layouts.iter().map(|layout| {
|
||||||
interner.get(*layout).alignment_bytes(interner, target_info)
|
interner
|
||||||
|
.get_repr(*layout)
|
||||||
|
.alignment_bytes(interner, target_info)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.max();
|
.max();
|
||||||
|
@ -2693,7 +2713,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LambdaSet(lambda_set) => interner
|
LambdaSet(lambda_set) => interner
|
||||||
.get(lambda_set.runtime_representation())
|
.get_repr(lambda_set.runtime_representation())
|
||||||
.alignment_bytes(interner, target_info),
|
.alignment_bytes(interner, target_info),
|
||||||
Builtin(builtin) => builtin.alignment_bytes(target_info),
|
Builtin(builtin) => builtin.alignment_bytes(target_info),
|
||||||
RecursivePointer(_) => target_info.ptr_width() as u32,
|
RecursivePointer(_) => target_info.ptr_width() as u32,
|
||||||
|
@ -2713,14 +2733,16 @@ impl<'a> LayoutRepr<'a> {
|
||||||
Struct { .. } => self.alignment_bytes(interner, target_info).max(ptr_width),
|
Struct { .. } => self.alignment_bytes(interner, target_info).max(ptr_width),
|
||||||
Union(union_layout) => union_layout.allocation_alignment_bytes(interner, target_info),
|
Union(union_layout) => union_layout.allocation_alignment_bytes(interner, target_info),
|
||||||
LambdaSet(lambda_set) => interner
|
LambdaSet(lambda_set) => interner
|
||||||
.get(lambda_set.runtime_representation())
|
.get_repr(lambda_set.runtime_representation())
|
||||||
.allocation_alignment_bytes(interner, target_info),
|
.allocation_alignment_bytes(interner, target_info),
|
||||||
RecursivePointer(_) => {
|
RecursivePointer(_) => {
|
||||||
unreachable!("should be looked up to get an actual layout")
|
unreachable!("should be looked up to get an actual layout")
|
||||||
}
|
}
|
||||||
Boxed(inner) => Ord::max(
|
Boxed(inner) => Ord::max(
|
||||||
ptr_width,
|
ptr_width,
|
||||||
interner.get(*inner).alignment_bytes(interner, target_info),
|
interner
|
||||||
|
.get_repr(*inner)
|
||||||
|
.alignment_bytes(interner, target_info),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2755,7 +2777,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
Builtin(builtin) => builtin.is_refcounted(),
|
Builtin(builtin) => builtin.is_refcounted(),
|
||||||
Struct(field_layouts) => field_layouts
|
Struct(field_layouts) => field_layouts
|
||||||
.iter()
|
.iter()
|
||||||
.any(|f| interner.get(*f).contains_refcounted(interner)),
|
.any(|f| interner.get_repr(*f).contains_refcounted(interner)),
|
||||||
Union(variant) => {
|
Union(variant) => {
|
||||||
use UnionLayout::*;
|
use UnionLayout::*;
|
||||||
|
|
||||||
|
@ -2763,7 +2785,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
NonRecursive(fields) => fields
|
NonRecursive(fields) => fields
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|ls| ls.iter())
|
.flat_map(|ls| ls.iter())
|
||||||
.any(|f| interner.get(*f).contains_refcounted(interner)),
|
.any(|f| interner.get_repr(*f).contains_refcounted(interner)),
|
||||||
Recursive(_)
|
Recursive(_)
|
||||||
| NullableWrapped { .. }
|
| NullableWrapped { .. }
|
||||||
| NullableUnwrapped { .. }
|
| NullableUnwrapped { .. }
|
||||||
|
@ -2771,7 +2793,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LambdaSet(lambda_set) => interner
|
LambdaSet(lambda_set) => interner
|
||||||
.get(lambda_set.runtime_representation())
|
.get_repr(lambda_set.runtime_representation())
|
||||||
.contains_refcounted(interner),
|
.contains_refcounted(interner),
|
||||||
RecursivePointer(_) => true,
|
RecursivePointer(_) => true,
|
||||||
Boxed(_) => true,
|
Boxed(_) => true,
|
||||||
|
@ -2805,27 +2827,27 @@ impl<'a> LayoutRepr<'a> {
|
||||||
Struct(field_layouts) => stack.extend(
|
Struct(field_layouts) => stack.extend(
|
||||||
field_layouts
|
field_layouts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|interned| interner.get(*interned).repr),
|
.map(|interned| interner.get_repr(*interned)),
|
||||||
),
|
),
|
||||||
Union(tag_union) => match tag_union {
|
Union(tag_union) => match tag_union {
|
||||||
UnionLayout::NonRecursive(tags) | UnionLayout::Recursive(tags) => {
|
UnionLayout::NonRecursive(tags) | UnionLayout::Recursive(tags) => {
|
||||||
for tag in tags {
|
for tag in tags {
|
||||||
stack.extend(tag.iter().map(|interned| interner.get(*interned).repr));
|
stack.extend(tag.iter().map(|interned| interner.get_repr(*interned)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnionLayout::NonNullableUnwrapped(fields) => {
|
UnionLayout::NonNullableUnwrapped(fields) => {
|
||||||
stack.extend(fields.iter().map(|interned| interner.get(*interned).repr));
|
stack.extend(fields.iter().map(|interned| interner.get_repr(*interned)));
|
||||||
}
|
}
|
||||||
UnionLayout::NullableWrapped { other_tags, .. } => {
|
UnionLayout::NullableWrapped { other_tags, .. } => {
|
||||||
for tag in other_tags {
|
for tag in other_tags {
|
||||||
stack.extend(tag.iter().map(|interned| interner.get(*interned).repr));
|
stack.extend(tag.iter().map(|interned| interner.get_repr(*interned)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnionLayout::NullableUnwrapped { other_fields, .. } => {
|
UnionLayout::NullableUnwrapped { other_fields, .. } => {
|
||||||
stack.extend(
|
stack.extend(
|
||||||
other_fields
|
other_fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|interned| interner.get(*interned).repr),
|
.map(|interned| interner.get_repr(*interned)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2894,9 +2916,12 @@ impl<'a> Layout<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_recursive_tag_union(self) -> bool {
|
pub fn is_recursive_tag_union<I>(self, interner: &I) -> bool
|
||||||
|
where
|
||||||
|
I: LayoutInterner<'a>,
|
||||||
|
{
|
||||||
matches!(
|
matches!(
|
||||||
self.repr,
|
self.repr(interner),
|
||||||
LayoutRepr::Union(
|
LayoutRepr::Union(
|
||||||
UnionLayout::NullableUnwrapped { .. }
|
UnionLayout::NullableUnwrapped { .. }
|
||||||
| UnionLayout::Recursive(_)
|
| UnionLayout::Recursive(_)
|
||||||
|
@ -3044,7 +3069,7 @@ impl<'a> Builtin<'a> {
|
||||||
let allocation = match self {
|
let allocation = match self {
|
||||||
Builtin::Str => ptr_width,
|
Builtin::Str => ptr_width,
|
||||||
Builtin::List(e) => {
|
Builtin::List(e) => {
|
||||||
let e = interner.get(*e);
|
let e = interner.get_repr(*e);
|
||||||
e.alignment_bytes(interner, target_info).max(ptr_width)
|
e.alignment_bytes(interner, target_info).max(ptr_width)
|
||||||
}
|
}
|
||||||
// The following are usually not heap-allocated, but they might be when inside a Box.
|
// The following are usually not heap-allocated, but they might be when inside a Box.
|
||||||
|
@ -3157,7 +3182,7 @@ fn layout_from_flat_type<'a>(
|
||||||
let inner_layout =
|
let inner_layout =
|
||||||
cached!(Layout::from_var(env, inner_var), criteria, env.subs);
|
cached!(Layout::from_var(env, inner_var), criteria, env.subs);
|
||||||
let boxed_layout = env.cache.put_in(Layout {
|
let boxed_layout = env.cache.put_in(Layout {
|
||||||
repr: LayoutRepr::Boxed(inner_layout),
|
repr: LayoutRepr::Boxed(inner_layout).direct(),
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3233,22 +3258,22 @@ fn layout_from_flat_type<'a>(
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(label, _)| &*arena.alloc_str(label.as_str())),
|
.map(|(label, _)| &*arena.alloc_str(label.as_str())),
|
||||||
arena,
|
arena,
|
||||||
);
|
)
|
||||||
|
.into_bump_slice();
|
||||||
|
let semantic = SemanticRepr::record(ordered_field_names);
|
||||||
|
|
||||||
let result = if sortables.len() == 1 {
|
let repr = if sortables.len() == 1 {
|
||||||
// If the record has only one field that isn't zero-sized,
|
// If the record has only one field that isn't zero-sized,
|
||||||
// unwrap it.
|
// unwrap it.
|
||||||
Ok(sortables.pop().unwrap().1)
|
let inner_repr = sortables.pop().unwrap().1;
|
||||||
|
inner_repr.newtype()
|
||||||
} else {
|
} else {
|
||||||
let layouts = Vec::from_iter_in(sortables.into_iter().map(|t| t.1), arena);
|
let layouts = Vec::from_iter_in(sortables.into_iter().map(|t| t.1), arena);
|
||||||
let struct_layout = Layout {
|
LayoutRepr::Struct(layouts.into_bump_slice()).direct()
|
||||||
repr: LayoutRepr::Struct(layouts.into_bump_slice()),
|
|
||||||
semantic: SemanticRepr::record(ordered_field_names.into_bump_slice()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(env.cache.put_in(struct_layout))
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let result = Ok(env.cache.put_in(Layout { repr, semantic }));
|
||||||
|
|
||||||
Cacheable(result, criteria)
|
Cacheable(result, criteria)
|
||||||
}
|
}
|
||||||
Tuple(elems, ext_var) => {
|
Tuple(elems, ext_var) => {
|
||||||
|
@ -3285,7 +3310,7 @@ fn layout_from_flat_type<'a>(
|
||||||
let field_layouts =
|
let field_layouts =
|
||||||
Vec::from_iter_in(sortables.into_iter().map(|t| t.1), arena).into_bump_slice();
|
Vec::from_iter_in(sortables.into_iter().map(|t| t.1), arena).into_bump_slice();
|
||||||
let struct_layout = Layout {
|
let struct_layout = Layout {
|
||||||
repr: LayoutRepr::Struct(field_layouts),
|
repr: LayoutRepr::Struct(field_layouts).direct(),
|
||||||
semantic: SemanticRepr::tuple(field_layouts.len()),
|
semantic: SemanticRepr::tuple(field_layouts.len()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3720,11 +3745,11 @@ where
|
||||||
layouts.sort_by(|layout1, layout2| {
|
layouts.sort_by(|layout1, layout2| {
|
||||||
let size1 = env
|
let size1 = env
|
||||||
.cache
|
.cache
|
||||||
.get_in(*layout1)
|
.get_repr(*layout1)
|
||||||
.alignment_bytes(&env.cache.interner, env.target_info);
|
.alignment_bytes(&env.cache.interner, env.target_info);
|
||||||
let size2 = env
|
let size2 = env
|
||||||
.cache
|
.cache
|
||||||
.get_in(*layout2)
|
.get_repr(*layout2)
|
||||||
.alignment_bytes(&env.cache.interner, env.target_info);
|
.alignment_bytes(&env.cache.interner, env.target_info);
|
||||||
|
|
||||||
size2.cmp(&size1)
|
size2.cmp(&size1)
|
||||||
|
@ -3782,11 +3807,11 @@ where
|
||||||
arg_layouts.sort_by(|layout1, layout2| {
|
arg_layouts.sort_by(|layout1, layout2| {
|
||||||
let size1 = env
|
let size1 = env
|
||||||
.cache
|
.cache
|
||||||
.get_in(*layout1)
|
.get_repr(*layout1)
|
||||||
.alignment_bytes(&env.cache.interner, env.target_info);
|
.alignment_bytes(&env.cache.interner, env.target_info);
|
||||||
let size2 = env
|
let size2 = env
|
||||||
.cache
|
.cache
|
||||||
.get_in(*layout2)
|
.get_repr(*layout2)
|
||||||
.alignment_bytes(&env.cache.interner, env.target_info);
|
.alignment_bytes(&env.cache.interner, env.target_info);
|
||||||
|
|
||||||
size2.cmp(&size1)
|
size2.cmp(&size1)
|
||||||
|
@ -3964,7 +3989,7 @@ where
|
||||||
== env
|
== env
|
||||||
.subs
|
.subs
|
||||||
.get_root_key_without_compacting(opt_rec_var.unwrap())
|
.get_root_key_without_compacting(opt_rec_var.unwrap())
|
||||||
&& layout.is_recursive_tag_union();
|
&& layout.is_recursive_tag_union(&env.cache.interner);
|
||||||
|
|
||||||
let arg_layout = if self_recursion {
|
let arg_layout = if self_recursion {
|
||||||
Layout::NAKED_RECURSIVE_PTR
|
Layout::NAKED_RECURSIVE_PTR
|
||||||
|
@ -3994,11 +4019,11 @@ where
|
||||||
arg_layouts.sort_by(|layout1, layout2| {
|
arg_layouts.sort_by(|layout1, layout2| {
|
||||||
let size1 = env
|
let size1 = env
|
||||||
.cache
|
.cache
|
||||||
.get_in(*layout1)
|
.get_repr(*layout1)
|
||||||
.alignment_bytes(&env.cache.interner, env.target_info);
|
.alignment_bytes(&env.cache.interner, env.target_info);
|
||||||
let size2 = env
|
let size2 = env
|
||||||
.cache
|
.cache
|
||||||
.get_in(*layout2)
|
.get_repr(*layout2)
|
||||||
.alignment_bytes(&env.cache.interner, env.target_info);
|
.alignment_bytes(&env.cache.interner, env.target_info);
|
||||||
|
|
||||||
size2.cmp(&size1)
|
size2.cmp(&size1)
|
||||||
|
@ -4133,13 +4158,13 @@ where
|
||||||
Never => Layout::VOID,
|
Never => Layout::VOID,
|
||||||
Unit => env
|
Unit => env
|
||||||
.cache
|
.cache
|
||||||
.put_in(Layout::new(LayoutRepr::UNIT, compute_semantic())),
|
.put_in(Layout::new(LayoutRepr::UNIT.direct(), compute_semantic())),
|
||||||
BoolUnion { .. } => env
|
BoolUnion { .. } => env
|
||||||
.cache
|
.cache
|
||||||
.put_in(Layout::new(LayoutRepr::BOOL, compute_semantic())),
|
.put_in(Layout::new(LayoutRepr::BOOL.direct(), compute_semantic())),
|
||||||
ByteUnion(_) => env
|
ByteUnion(_) => env
|
||||||
.cache
|
.cache
|
||||||
.put_in(Layout::new(LayoutRepr::U8, compute_semantic())),
|
.put_in(Layout::new(LayoutRepr::U8.direct(), compute_semantic())),
|
||||||
Newtype {
|
Newtype {
|
||||||
arguments: field_layouts,
|
arguments: field_layouts,
|
||||||
..
|
..
|
||||||
|
@ -4148,7 +4173,7 @@ where
|
||||||
field_layouts[0]
|
field_layouts[0]
|
||||||
} else {
|
} else {
|
||||||
env.cache
|
env.cache
|
||||||
.put_in_no_semantic(LayoutRepr::struct_(field_layouts.into_bump_slice()))
|
.put_in_direct_no_semantic(LayoutRepr::struct_(field_layouts.into_bump_slice()))
|
||||||
};
|
};
|
||||||
|
|
||||||
answer1
|
answer1
|
||||||
|
@ -4159,8 +4184,9 @@ where
|
||||||
if data_tag_arguments.len() == 1 {
|
if data_tag_arguments.len() == 1 {
|
||||||
data_tag_arguments[0]
|
data_tag_arguments[0]
|
||||||
} else {
|
} else {
|
||||||
env.cache
|
env.cache.put_in_direct_no_semantic(LayoutRepr::struct_(
|
||||||
.put_in_no_semantic(LayoutRepr::struct_(data_tag_arguments.into_bump_slice()))
|
data_tag_arguments.into_bump_slice(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Wrapped(variant) => {
|
Wrapped(variant) => {
|
||||||
|
@ -4176,7 +4202,8 @@ where
|
||||||
let layout = Layout {
|
let layout = Layout {
|
||||||
repr: LayoutRepr::Union(UnionLayout::NonRecursive(
|
repr: LayoutRepr::Union(UnionLayout::NonRecursive(
|
||||||
tag_layouts.into_bump_slice(),
|
tag_layouts.into_bump_slice(),
|
||||||
)),
|
))
|
||||||
|
.direct(),
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
};
|
};
|
||||||
env.cache.put_in(layout)
|
env.cache.put_in(layout)
|
||||||
|
@ -4292,14 +4319,14 @@ where
|
||||||
env.cache.interner.insert_recursive(
|
env.cache.interner.insert_recursive(
|
||||||
env.arena,
|
env.arena,
|
||||||
Layout {
|
Layout {
|
||||||
repr: LayoutRepr::Union(union_layout),
|
repr: LayoutRepr::Union(union_layout).direct(),
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// There are no naked recursion pointers, so we can insert the layout as-is.
|
// There are no naked recursion pointers, so we can insert the layout as-is.
|
||||||
env.cache.interner.insert(Layout {
|
env.cache.interner.insert(Layout {
|
||||||
repr: LayoutRepr::Union(union_layout),
|
repr: LayoutRepr::Union(union_layout).direct(),
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -4435,7 +4462,7 @@ pub(crate) fn list_layout_from_elem<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let list_layout = env.cache.put_in(Layout {
|
let list_layout = env.cache.put_in(Layout {
|
||||||
repr: LayoutRepr::Builtin(Builtin::List(element_layout)),
|
repr: LayoutRepr::Builtin(Builtin::List(element_layout)).direct(),
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -4589,8 +4616,12 @@ pub fn cmp_fields<'a, L: Ord, I>(
|
||||||
where
|
where
|
||||||
I: LayoutInterner<'a>,
|
I: LayoutInterner<'a>,
|
||||||
{
|
{
|
||||||
let size1 = interner.get(layout1).alignment_bytes(interner, target_info);
|
let size1 = interner
|
||||||
let size2 = interner.get(layout2).alignment_bytes(interner, target_info);
|
.get_repr(layout1)
|
||||||
|
.alignment_bytes(interner, target_info);
|
||||||
|
let size2 = interner
|
||||||
|
.get_repr(layout2)
|
||||||
|
.alignment_bytes(interner, target_info);
|
||||||
|
|
||||||
size2.cmp(&size1).then(label1.cmp(label2))
|
size2.cmp(&size1).then(label1.cmp(label2))
|
||||||
}
|
}
|
||||||
|
@ -4613,19 +4644,16 @@ mod test {
|
||||||
|
|
||||||
let a = &[Layout::UNIT] as &[_];
|
let a = &[Layout::UNIT] as &[_];
|
||||||
let b = &[interner.insert(Layout {
|
let b = &[interner.insert(Layout {
|
||||||
repr: LayoutRepr::LambdaSet(lambda_set),
|
repr: LayoutRepr::LambdaSet(lambda_set).direct(),
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
})] as &[_];
|
})] as &[_];
|
||||||
let tt = [a, b];
|
let tt = [a, b];
|
||||||
|
|
||||||
let layout = Layout {
|
let repr = LayoutRepr::Union(UnionLayout::NonRecursive(&tt));
|
||||||
repr: LayoutRepr::Union(UnionLayout::NonRecursive(&tt)),
|
|
||||||
semantic: SemanticRepr::NONE,
|
|
||||||
};
|
|
||||||
|
|
||||||
let target_info = TargetInfo::default_x86_64();
|
let target_info = TargetInfo::default_x86_64();
|
||||||
assert_eq!(layout.stack_size(&interner, target_info), 1);
|
assert_eq!(repr.stack_size(&interner, target_info), 1);
|
||||||
assert_eq!(layout.alignment_bytes(&interner, target_info), 1);
|
assert_eq!(repr.alignment_bytes(&interner, target_info), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -4633,29 +4661,28 @@ mod test {
|
||||||
let mut interner = STLayoutInterner::with_capacity(4, TargetInfo::default_x86_64());
|
let mut interner = STLayoutInterner::with_capacity(4, TargetInfo::default_x86_64());
|
||||||
|
|
||||||
let ok_tag = &[interner.insert(Layout {
|
let ok_tag = &[interner.insert(Layout {
|
||||||
repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::U32)),
|
repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::U32)).direct(),
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
})];
|
})];
|
||||||
let err_tag = &[Layout::UNIT];
|
let err_tag = &[Layout::UNIT];
|
||||||
let tags = [ok_tag as &[_], err_tag as &[_]];
|
let tags = [ok_tag as &[_], err_tag as &[_]];
|
||||||
let union_layout = UnionLayout::NonRecursive(&tags as &[_]);
|
let union_layout = UnionLayout::NonRecursive(&tags as &[_]);
|
||||||
let layout = Layout {
|
let repr = LayoutRepr::Union(union_layout);
|
||||||
repr: LayoutRepr::Union(union_layout),
|
|
||||||
semantic: SemanticRepr::NONE,
|
|
||||||
};
|
|
||||||
|
|
||||||
let target_info = TargetInfo::default_x86_64();
|
let target_info = TargetInfo::default_x86_64();
|
||||||
assert_eq!(
|
assert_eq!(repr.stack_size_without_alignment(&interner, target_info), 8);
|
||||||
layout.stack_size_without_alignment(&interner, target_info),
|
|
||||||
8
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn void_stack_size() {
|
fn void_stack_size() {
|
||||||
let interner = STLayoutInterner::with_capacity(4, TargetInfo::default_x86_64());
|
let interner = STLayoutInterner::with_capacity(4, TargetInfo::default_x86_64());
|
||||||
let target_info = TargetInfo::default_x86_64();
|
let target_info = TargetInfo::default_x86_64();
|
||||||
assert_eq!(Layout::VOID_NAKED.stack_size(&interner, target_info), 0);
|
assert_eq!(
|
||||||
|
Layout::VOID_NAKED
|
||||||
|
.repr(&interner)
|
||||||
|
.stack_size(&interner, target_info),
|
||||||
|
0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -14,7 +14,7 @@ use roc_target::TargetInfo;
|
||||||
|
|
||||||
use crate::layout::LayoutRepr;
|
use crate::layout::LayoutRepr;
|
||||||
|
|
||||||
use super::{LambdaSet, Layout, SeenRecPtrs, SemanticRepr, UnionLayout};
|
use super::{LambdaSet, Layout, LayoutWrapper, SeenRecPtrs, SemanticRepr, UnionLayout};
|
||||||
|
|
||||||
macro_rules! cache_interned_layouts {
|
macro_rules! cache_interned_layouts {
|
||||||
($($i:literal, $name:ident, $vis:vis, $layout:expr)*; $total_constants:literal) => {
|
($($i:literal, $name:ident, $vis:vis, $layout:expr)*; $total_constants:literal) => {
|
||||||
|
@ -50,7 +50,7 @@ macro_rules! cache_interned_layouts {
|
||||||
macro_rules! nosema {
|
macro_rules! nosema {
|
||||||
($r:expr) => {
|
($r:expr) => {
|
||||||
Layout {
|
Layout {
|
||||||
repr: $r,
|
repr: $r.direct(),
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -119,11 +119,11 @@ impl_to_from_int_width! {
|
||||||
|
|
||||||
impl<'a> Layout<'a> {
|
impl<'a> Layout<'a> {
|
||||||
pub(super) const VOID_NAKED: Self = Layout {
|
pub(super) const VOID_NAKED: Self = Layout {
|
||||||
repr: LayoutRepr::Union(UnionLayout::NonRecursive(&[])),
|
repr: LayoutRepr::Union(UnionLayout::NonRecursive(&[])).direct(),
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
};
|
};
|
||||||
pub(super) const UNIT_NAKED: Self = Layout {
|
pub(super) const UNIT_NAKED: Self = Layout {
|
||||||
repr: LayoutRepr::Struct(&[]),
|
repr: LayoutRepr::Struct(&[]).direct(),
|
||||||
semantic: SemanticRepr::EMPTY_RECORD,
|
semantic: SemanticRepr::EMPTY_RECORD,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -154,8 +154,8 @@ pub trait LayoutInterner<'a>: Sized {
|
||||||
|
|
||||||
/// Interns a value with no semantic representation, returning its interned representation.
|
/// Interns a value with no semantic representation, returning its interned representation.
|
||||||
/// If the value has been interned before, the old interned representation will be re-used.
|
/// If the value has been interned before, the old interned representation will be re-used.
|
||||||
fn insert_no_semantic(&mut self, repr: LayoutRepr<'a>) -> InLayout<'a> {
|
fn insert_direct_no_semantic(&mut self, repr: LayoutRepr<'a>) -> InLayout<'a> {
|
||||||
self.insert(Layout::no_semantic(repr))
|
self.insert(Layout::no_semantic(repr.direct()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a [LambdaSet], including caching the [LayoutRepr::LambdaSet] representation of the
|
/// Creates a [LambdaSet], including caching the [LayoutRepr::LambdaSet] representation of the
|
||||||
|
@ -181,60 +181,78 @@ pub trait LayoutInterner<'a>: Sized {
|
||||||
//
|
//
|
||||||
// Convenience methods
|
// Convenience methods
|
||||||
|
|
||||||
|
fn get_repr(&self, mut key: InLayout<'a>) -> LayoutRepr<'a> {
|
||||||
|
loop {
|
||||||
|
match self.get(key).repr {
|
||||||
|
LayoutWrapper::Direct(repr) => return repr,
|
||||||
|
LayoutWrapper::Newtype(inner) => key = inner,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_semantic(&self, key: InLayout<'a>) -> SemanticRepr<'a> {
|
||||||
|
self.get(key).semantic
|
||||||
|
}
|
||||||
|
|
||||||
fn eq_repr(&self, a: InLayout<'a>, b: InLayout<'a>) -> bool {
|
fn eq_repr(&self, a: InLayout<'a>, b: InLayout<'a>) -> bool {
|
||||||
self.get(a).repr == self.get(b).repr
|
self.get_repr(a) == self.get_repr(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn target_info(&self) -> TargetInfo;
|
fn target_info(&self) -> TargetInfo;
|
||||||
|
|
||||||
fn alignment_bytes(&self, layout: InLayout<'a>) -> u32 {
|
fn alignment_bytes(&self, layout: InLayout<'a>) -> u32 {
|
||||||
self.get(layout).alignment_bytes(self, self.target_info())
|
self.get_repr(layout)
|
||||||
|
.alignment_bytes(self, self.target_info())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allocation_alignment_bytes(&self, layout: InLayout<'a>) -> u32 {
|
fn allocation_alignment_bytes(&self, layout: InLayout<'a>) -> u32 {
|
||||||
self.get(layout)
|
self.get_repr(layout)
|
||||||
.allocation_alignment_bytes(self, self.target_info())
|
.allocation_alignment_bytes(self, self.target_info())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stack_size(&self, layout: InLayout<'a>) -> u32 {
|
fn stack_size(&self, layout: InLayout<'a>) -> u32 {
|
||||||
self.get(layout).stack_size(self, self.target_info())
|
self.get_repr(layout).stack_size(self, self.target_info())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stack_size_and_alignment(&self, layout: InLayout<'a>) -> (u32, u32) {
|
fn stack_size_and_alignment(&self, layout: InLayout<'a>) -> (u32, u32) {
|
||||||
self.get(layout)
|
self.get_repr(layout)
|
||||||
.stack_size_and_alignment(self, self.target_info())
|
.stack_size_and_alignment(self, self.target_info())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stack_size_without_alignment(&self, layout: InLayout<'a>) -> u32 {
|
fn stack_size_without_alignment(&self, layout: InLayout<'a>) -> u32 {
|
||||||
self.get(layout)
|
self.get_repr(layout)
|
||||||
.stack_size_without_alignment(self, self.target_info())
|
.stack_size_without_alignment(self, self.target_info())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contains_refcounted(&self, layout: InLayout<'a>) -> bool {
|
fn contains_refcounted(&self, layout: InLayout<'a>) -> bool {
|
||||||
self.get(layout).contains_refcounted(self)
|
self.get_repr(layout).contains_refcounted(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_refcounted(&self, layout: InLayout<'a>) -> bool {
|
fn is_refcounted(&self, layout: InLayout<'a>) -> bool {
|
||||||
self.get(layout).is_refcounted()
|
self.get_repr(layout).is_refcounted()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_passed_by_reference(&self, layout: InLayout<'a>) -> bool {
|
fn is_passed_by_reference(&self, layout: InLayout<'a>) -> bool {
|
||||||
self.get(layout)
|
self.get_repr(layout)
|
||||||
.is_passed_by_reference(self, self.target_info())
|
.is_passed_by_reference(self, self.target_info())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn runtime_representation(&self, layout: InLayout<'a>) -> Layout<'a> {
|
fn runtime_representation(&self, layout: InLayout<'a>) -> LayoutRepr<'a> {
|
||||||
self.get(layout).runtime_representation(self)
|
self.get_repr(self.runtime_representation_in(layout))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn runtime_representation_in(&self, layout: InLayout<'a>) -> InLayout<'a> {
|
fn runtime_representation_in(&self, layout: InLayout<'a>) -> InLayout<'a> {
|
||||||
Layout::runtime_representation_in(layout, self)
|
Layout::runtime_representation_in(layout, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn chase_recursive(&self, mut layout: InLayout<'a>) -> Layout<'a> {
|
fn has_varying_stack_size(&self, layout: InLayout<'a>, arena: &'a Bump) -> bool {
|
||||||
|
self.get_repr(layout).has_varying_stack_size(self, arena)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn chase_recursive(&self, mut layout: InLayout<'a>) -> LayoutRepr<'a> {
|
||||||
loop {
|
loop {
|
||||||
let lay = self.get(layout);
|
let lay = self.get_repr(layout);
|
||||||
match lay.repr {
|
match lay {
|
||||||
LayoutRepr::RecursivePointer(l) => layout = l,
|
LayoutRepr::RecursivePointer(l) => layout = l,
|
||||||
_ => return lay,
|
_ => return lay,
|
||||||
}
|
}
|
||||||
|
@ -243,7 +261,7 @@ pub trait LayoutInterner<'a>: Sized {
|
||||||
|
|
||||||
fn chase_recursive_in(&self, mut layout: InLayout<'a>) -> InLayout<'a> {
|
fn chase_recursive_in(&self, mut layout: InLayout<'a>) -> InLayout<'a> {
|
||||||
loop {
|
loop {
|
||||||
match self.get(layout).repr {
|
match self.get_repr(layout) {
|
||||||
LayoutRepr::RecursivePointer(l) => layout = l,
|
LayoutRepr::RecursivePointer(l) => layout = l,
|
||||||
_ => return layout,
|
_ => return layout,
|
||||||
}
|
}
|
||||||
|
@ -251,7 +269,7 @@ pub trait LayoutInterner<'a>: Sized {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn safe_to_memcpy(&self, layout: InLayout<'a>) -> bool {
|
fn safe_to_memcpy(&self, layout: InLayout<'a>) -> bool {
|
||||||
self.get(layout).safe_to_memcpy(self)
|
self.get_repr(layout).safe_to_memcpy(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if two layouts are equivalent up to isomorphism.
|
/// Checks if two layouts are equivalent up to isomorphism.
|
||||||
|
@ -298,7 +316,7 @@ pub trait LayoutInterner<'a>: Sized {
|
||||||
{
|
{
|
||||||
use LayoutRepr::*;
|
use LayoutRepr::*;
|
||||||
|
|
||||||
match self.get(layout).repr {
|
match self.get_repr(layout) {
|
||||||
Builtin(builtin) => builtin.to_doc(alloc, self, seen_rec, parens),
|
Builtin(builtin) => builtin.to_doc(alloc, self, seen_rec, parens),
|
||||||
Struct(field_layouts) => {
|
Struct(field_layouts) => {
|
||||||
let fields_doc = field_layouts
|
let fields_doc = field_layouts
|
||||||
|
@ -455,6 +473,10 @@ impl<'a> InLayout<'a> {
|
||||||
Self(index, PhantomData)
|
Self(index, PhantomData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) const fn newtype(self) -> LayoutWrapper<'a> {
|
||||||
|
LayoutWrapper::Newtype(self)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn index(&self) -> usize {
|
pub fn index(&self) -> usize {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
@ -665,7 +687,7 @@ impl<'a> GlobalLayoutInterner<'a> {
|
||||||
..normalized
|
..normalized
|
||||||
};
|
};
|
||||||
let lambda_set_layout = Layout {
|
let lambda_set_layout = Layout {
|
||||||
repr: LayoutRepr::LambdaSet(full_lambda_set),
|
repr: LayoutRepr::LambdaSet(full_lambda_set).direct(),
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -974,7 +996,7 @@ macro_rules! st_impl {
|
||||||
full_layout: slot,
|
full_layout: slot,
|
||||||
};
|
};
|
||||||
let lay = Layout {
|
let lay = Layout {
|
||||||
repr: LayoutRepr::LambdaSet(lambda_set),
|
repr: LayoutRepr::LambdaSet(lambda_set).direct(),
|
||||||
semantic: SemanticRepr::NONE
|
semantic: SemanticRepr::NONE
|
||||||
};
|
};
|
||||||
self.vec[slot.0] = lay;
|
self.vec[slot.0] = lay;
|
||||||
|
@ -1035,7 +1057,7 @@ mod reify {
|
||||||
use bumpalo::{collections::Vec, Bump};
|
use bumpalo::{collections::Vec, Bump};
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
|
|
||||||
use crate::layout::{Builtin, LambdaSet, Layout, LayoutRepr, UnionLayout};
|
use crate::layout::{Builtin, LambdaSet, Layout, LayoutRepr, LayoutWrapper, UnionLayout};
|
||||||
|
|
||||||
use super::{InLayout, LayoutInterner, NeedsRecursionPointerFixup};
|
use super::{InLayout, LayoutInterner, NeedsRecursionPointerFixup};
|
||||||
|
|
||||||
|
@ -1046,7 +1068,24 @@ mod reify {
|
||||||
slot: InLayout<'a>,
|
slot: InLayout<'a>,
|
||||||
normalized_layout: Layout<'a>,
|
normalized_layout: Layout<'a>,
|
||||||
) -> Layout<'a> {
|
) -> Layout<'a> {
|
||||||
let repr = match normalized_layout.repr {
|
let Layout { repr, semantic } = normalized_layout;
|
||||||
|
let reified_repr = match repr {
|
||||||
|
LayoutWrapper::Direct(repr) => {
|
||||||
|
reify_recursive_layout_repr(arena, interner, slot, repr).direct()
|
||||||
|
}
|
||||||
|
LayoutWrapper::Newtype(inner) => reify_layout(arena, interner, slot, inner).newtype(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Layout::new(reified_repr, semantic)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reify_recursive_layout_repr<'a>(
|
||||||
|
arena: &'a Bump,
|
||||||
|
interner: &mut impl LayoutInterner<'a>,
|
||||||
|
slot: InLayout<'a>,
|
||||||
|
repr: LayoutRepr<'a>,
|
||||||
|
) -> LayoutRepr<'a> {
|
||||||
|
match repr {
|
||||||
LayoutRepr::Builtin(builtin) => {
|
LayoutRepr::Builtin(builtin) => {
|
||||||
LayoutRepr::Builtin(reify_builtin(arena, interner, slot, builtin))
|
LayoutRepr::Builtin(reify_builtin(arena, interner, slot, builtin))
|
||||||
}
|
}
|
||||||
|
@ -1063,10 +1102,6 @@ mod reify {
|
||||||
// another recursive union's layout, do not change it.
|
// another recursive union's layout, do not change it.
|
||||||
LayoutRepr::RecursivePointer(if l == Layout::VOID { slot } else { l })
|
LayoutRepr::RecursivePointer(if l == Layout::VOID { slot } else { l })
|
||||||
}
|
}
|
||||||
};
|
|
||||||
Layout {
|
|
||||||
repr,
|
|
||||||
semantic: normalized_layout.semantic,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1244,7 +1279,7 @@ mod equiv {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
use LayoutRepr::*;
|
use LayoutRepr::*;
|
||||||
match (interner.get(l1).repr, interner.get(l2).repr) {
|
match (interner.get_repr(l1), interner.get_repr(l2)) {
|
||||||
(RecursivePointer(rec), _) => stack.push((rec, l2)),
|
(RecursivePointer(rec), _) => stack.push((rec, l2)),
|
||||||
(_, RecursivePointer(rec)) => stack.push((l1, rec)),
|
(_, RecursivePointer(rec)) => stack.push((l1, rec)),
|
||||||
(Builtin(b1), Builtin(b2)) => {
|
(Builtin(b1), Builtin(b2)) => {
|
||||||
|
@ -1340,7 +1375,7 @@ mod equiv {
|
||||||
pub mod dbg {
|
pub mod dbg {
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
|
|
||||||
use crate::layout::{Builtin, LambdaSet, Layout, LayoutRepr, UnionLayout};
|
use crate::layout::{Builtin, LambdaSet, LayoutRepr, UnionLayout};
|
||||||
|
|
||||||
use super::{InLayout, LayoutInterner};
|
use super::{InLayout, LayoutInterner};
|
||||||
|
|
||||||
|
@ -1348,7 +1383,8 @@ pub mod dbg {
|
||||||
|
|
||||||
impl<'a, 'r, I: LayoutInterner<'a>> std::fmt::Debug for Dbg<'a, 'r, I> {
|
impl<'a, 'r, I: LayoutInterner<'a>> std::fmt::Debug for Dbg<'a, 'r, I> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Layout { repr, semantic } = self.0.get(self.1);
|
let repr = self.0.get_repr(self.1);
|
||||||
|
let semantic = self.0.get_semantic(self.1);
|
||||||
|
|
||||||
f.debug_struct("Layout")
|
f.debug_struct("Layout")
|
||||||
.field("repr", &DbgRepr(self.0, &repr))
|
.field("repr", &DbgRepr(self.0, &repr))
|
||||||
|
@ -1544,7 +1580,7 @@ mod insert_lambda_set {
|
||||||
let lambda_set =
|
let lambda_set =
|
||||||
interner.insert_lambda_set(arena, TEST_ARGS, TEST_RET, TEST_SET, FIXUP, Layout::UNIT);
|
interner.insert_lambda_set(arena, TEST_ARGS, TEST_RET, TEST_SET, FIXUP, Layout::UNIT);
|
||||||
let lambda_set_layout_in = interner.insert(Layout {
|
let lambda_set_layout_in = interner.insert(Layout {
|
||||||
repr: LayoutRepr::LambdaSet(lambda_set),
|
repr: LayoutRepr::LambdaSet(lambda_set).direct(),
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
});
|
});
|
||||||
assert_eq!(lambda_set.full_layout, lambda_set_layout_in);
|
assert_eq!(lambda_set.full_layout, lambda_set_layout_in);
|
||||||
|
@ -1603,15 +1639,16 @@ mod insert_recursive_layout {
|
||||||
|
|
||||||
fn make_layout<'a>(arena: &'a Bump, interner: &mut impl LayoutInterner<'a>) -> Layout<'a> {
|
fn make_layout<'a>(arena: &'a Bump, interner: &mut impl LayoutInterner<'a>) -> Layout<'a> {
|
||||||
let list_rec = Layout {
|
let list_rec = Layout {
|
||||||
repr: LayoutRepr::Builtin(Builtin::List(Layout::NAKED_RECURSIVE_PTR)),
|
repr: LayoutRepr::Builtin(Builtin::List(Layout::NAKED_RECURSIVE_PTR)).direct(),
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
};
|
};
|
||||||
let repr = LayoutRepr::Union(UnionLayout::Recursive(&*arena.alloc([
|
let repr = LayoutRepr::Union(UnionLayout::Recursive(&*arena.alloc([
|
||||||
&*arena.alloc([interner.insert(list_rec)]),
|
&*arena.alloc([interner.insert(list_rec)]),
|
||||||
&*arena.alloc_slice_fill_iter([interner.insert_no_semantic(LayoutRepr::struct_(
|
&*arena.alloc_slice_fill_iter([interner.insert_direct_no_semantic(
|
||||||
&*arena.alloc([Layout::NAKED_RECURSIVE_PTR]),
|
LayoutRepr::struct_(&*arena.alloc([Layout::NAKED_RECURSIVE_PTR])),
|
||||||
))]),
|
)]),
|
||||||
])));
|
])))
|
||||||
|
.direct();
|
||||||
Layout {
|
Layout {
|
||||||
repr,
|
repr,
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
|
@ -1619,11 +1656,11 @@ mod insert_recursive_layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rec_ptr_index<'a>(interner: &impl LayoutInterner<'a>, layout: InLayout<'a>) -> usize {
|
fn get_rec_ptr_index<'a>(interner: &impl LayoutInterner<'a>, layout: InLayout<'a>) -> usize {
|
||||||
match interner.chase_recursive(layout).repr {
|
match interner.chase_recursive(layout) {
|
||||||
LayoutRepr::Union(UnionLayout::Recursive(&[&[l1], &[l2]])) => {
|
LayoutRepr::Union(UnionLayout::Recursive(&[&[l1], &[l2]])) => {
|
||||||
match (interner.get(l1).repr, interner.get(l2).repr) {
|
match (interner.get_repr(l1), interner.get_repr(l2)) {
|
||||||
(LayoutRepr::Builtin(Builtin::List(l1)), LayoutRepr::Struct(&[l2])) => {
|
(LayoutRepr::Builtin(Builtin::List(l1)), LayoutRepr::Struct(&[l2])) => {
|
||||||
match (interner.get(l1).repr, interner.get(l2).repr) {
|
match (interner.get_repr(l1), interner.get_repr(l2)) {
|
||||||
(
|
(
|
||||||
LayoutRepr::RecursivePointer(i1),
|
LayoutRepr::RecursivePointer(i1),
|
||||||
LayoutRepr::RecursivePointer(i2),
|
LayoutRepr::RecursivePointer(i2),
|
||||||
|
|
|
@ -1277,7 +1277,7 @@ fn symbol_layout_reusability<'a>(
|
||||||
symbol: &Symbol,
|
symbol: &Symbol,
|
||||||
layout: &InLayout<'a>,
|
layout: &InLayout<'a>,
|
||||||
) -> Reuse<'a> {
|
) -> Reuse<'a> {
|
||||||
match layout_interner.get(*layout).repr {
|
match layout_interner.get_repr(*layout) {
|
||||||
LayoutRepr::Union(union_layout) => {
|
LayoutRepr::Union(union_layout) => {
|
||||||
can_reuse_union_layout_tag(union_layout, environment.get_symbol_tag(symbol))
|
can_reuse_union_layout_tag(union_layout, environment.get_symbol_tag(symbol))
|
||||||
}
|
}
|
||||||
|
|
|
@ -932,6 +932,29 @@ fn encode_derived_generic_tag_with_different_field_types() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||||
|
fn specialize_unique_newtype_records() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test"
|
||||||
|
imports [Encode, Json]
|
||||||
|
provides [main] to "./platform"
|
||||||
|
|
||||||
|
main =
|
||||||
|
when Str.fromUtf8 (Encode.toBytes {a: Bool.true} Json.json) is
|
||||||
|
Ok s -> when Str.fromUtf8 (Encode.toBytes {b: Bool.true} Json.json) is
|
||||||
|
Ok t -> "\(s)\(t)"
|
||||||
|
_ -> "<bad>"
|
||||||
|
_ -> "<bad>"
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
RocStr::from(r#"{"a":true}{"b":true}"#),
|
||||||
|
RocStr
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||||
fn decode_use_stdlib() {
|
fn decode_use_stdlib() {
|
||||||
|
|
|
@ -27,7 +27,7 @@ fn width_and_alignment_u8_u8() {
|
||||||
let t = &[Layout::U8] as &[_];
|
let t = &[Layout::U8] as &[_];
|
||||||
let tt = [t, t];
|
let tt = [t, t];
|
||||||
|
|
||||||
let layout = Layout::no_semantic(LayoutRepr::Union(UnionLayout::NonRecursive(&tt)));
|
let layout = LayoutRepr::Union(UnionLayout::NonRecursive(&tt));
|
||||||
|
|
||||||
assert_eq!(layout.alignment_bytes(&interner, target_info), 1);
|
assert_eq!(layout.alignment_bytes(&interner, target_info), 1);
|
||||||
assert_eq!(layout.stack_size(&interner, target_info), 2);
|
assert_eq!(layout.stack_size(&interner, target_info), 2);
|
||||||
|
|
|
@ -97,7 +97,7 @@ procedure Test.2 (Test.6):
|
||||||
decref Test.6;
|
decref Test.6;
|
||||||
jump #Derived_gen.0;
|
jump #Derived_gen.0;
|
||||||
else
|
else
|
||||||
let Test.9 : List [<r>C List *self, C *self] = UnionAtIndex (Id 0) (Index 0) Test.6;
|
let Test.9 : List [<r>C List [<r>C List *self, C *self], C [<r>C List *self, C *self]] = UnionAtIndex (Id 0) (Index 0) Test.6;
|
||||||
joinpoint #Derived_gen.2:
|
joinpoint #Derived_gen.2:
|
||||||
let Test.24 : {} = Struct {};
|
let Test.24 : {} = Struct {};
|
||||||
let Test.23 : List Str = CallByName List.5 Test.9 Test.24;
|
let Test.23 : List Str = CallByName List.5 Test.9 Test.24;
|
||||||
|
@ -116,7 +116,7 @@ procedure Test.2 (Test.6):
|
||||||
jump #Derived_gen.2;
|
jump #Derived_gen.2;
|
||||||
|
|
||||||
procedure Test.0 ():
|
procedure Test.0 ():
|
||||||
let Test.32 : List [<r>C List *self, C *self] = Array [];
|
let Test.32 : List [<r>C List [<r>C List *self, C *self], C [<r>C List *self, C *self]] = Array [];
|
||||||
let Test.15 : [<r>C List *self, C *self] = TagId(0) Test.32;
|
let Test.15 : [<r>C List *self, C *self] = TagId(0) Test.32;
|
||||||
let Test.14 : Str = CallByName Test.2 Test.15;
|
let Test.14 : Str = CallByName Test.2 Test.15;
|
||||||
ret Test.14;
|
ret Test.14;
|
||||||
|
|
12
crates/compiler/test_mono/generated/dbg_in_expect.txt
Normal file
12
crates/compiler/test_mono/generated/dbg_in_expect.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
procedure Bool.2 ():
|
||||||
|
let Bool.23 : Int1 = true;
|
||||||
|
ret Bool.23;
|
||||||
|
|
||||||
|
procedure Test.1 ():
|
||||||
|
let Test.0 : Str = "";
|
||||||
|
dbg Test.0;
|
||||||
|
dec Test.0;
|
||||||
|
let Test.3 : Int1 = CallByName Bool.2;
|
||||||
|
expect Test.3;
|
||||||
|
let Test.2 : {} = Struct {};
|
||||||
|
ret Test.2;
|
|
@ -1331,14 +1331,14 @@ procedure TotallyNotJson.82 (TotallyNotJson.802, TotallyNotJson.803):
|
||||||
|
|
||||||
procedure TotallyNotJson.832 (TotallyNotJson.1493):
|
procedure TotallyNotJson.832 (TotallyNotJson.1493):
|
||||||
let TotallyNotJson.1868 : List Str = StructAtIndex 1 TotallyNotJson.1493;
|
let TotallyNotJson.1868 : List Str = StructAtIndex 1 TotallyNotJson.1493;
|
||||||
let #Derived_gen.30 : List Str = StructAtIndex 0 TotallyNotJson.1493;
|
let #Derived_gen.29 : List Str = StructAtIndex 0 TotallyNotJson.1493;
|
||||||
dec #Derived_gen.30;
|
dec #Derived_gen.29;
|
||||||
ret TotallyNotJson.1868;
|
ret TotallyNotJson.1868;
|
||||||
|
|
||||||
procedure TotallyNotJson.840 (TotallyNotJson.1214):
|
procedure TotallyNotJson.840 (TotallyNotJson.1214):
|
||||||
let TotallyNotJson.1589 : List Str = StructAtIndex 1 TotallyNotJson.1214;
|
let TotallyNotJson.1589 : List Str = StructAtIndex 1 TotallyNotJson.1214;
|
||||||
let #Derived_gen.29 : List Str = StructAtIndex 0 TotallyNotJson.1214;
|
let #Derived_gen.30 : List Str = StructAtIndex 0 TotallyNotJson.1214;
|
||||||
dec #Derived_gen.29;
|
dec #Derived_gen.30;
|
||||||
ret TotallyNotJson.1589;
|
ret TotallyNotJson.1589;
|
||||||
|
|
||||||
procedure TotallyNotJson.87 (TotallyNotJson.809):
|
procedure TotallyNotJson.87 (TotallyNotJson.809):
|
||||||
|
|
|
@ -1222,14 +1222,14 @@ procedure TotallyNotJson.82 (TotallyNotJson.802, TotallyNotJson.803):
|
||||||
|
|
||||||
procedure TotallyNotJson.832 (TotallyNotJson.1493):
|
procedure TotallyNotJson.832 (TotallyNotJson.1493):
|
||||||
let TotallyNotJson.1494 : List Str = StructAtIndex 1 TotallyNotJson.1493;
|
let TotallyNotJson.1494 : List Str = StructAtIndex 1 TotallyNotJson.1493;
|
||||||
let #Derived_gen.19 : List Str = StructAtIndex 0 TotallyNotJson.1493;
|
let #Derived_gen.20 : List Str = StructAtIndex 0 TotallyNotJson.1493;
|
||||||
dec #Derived_gen.19;
|
dec #Derived_gen.20;
|
||||||
ret TotallyNotJson.1494;
|
ret TotallyNotJson.1494;
|
||||||
|
|
||||||
procedure TotallyNotJson.840 (TotallyNotJson.1214):
|
procedure TotallyNotJson.840 (TotallyNotJson.1214):
|
||||||
let TotallyNotJson.1215 : List Str = StructAtIndex 1 TotallyNotJson.1214;
|
let TotallyNotJson.1215 : List Str = StructAtIndex 1 TotallyNotJson.1214;
|
||||||
let #Derived_gen.20 : List Str = StructAtIndex 0 TotallyNotJson.1214;
|
let #Derived_gen.19 : List Str = StructAtIndex 0 TotallyNotJson.1214;
|
||||||
dec #Derived_gen.20;
|
dec #Derived_gen.19;
|
||||||
ret TotallyNotJson.1215;
|
ret TotallyNotJson.1215;
|
||||||
|
|
||||||
procedure TotallyNotJson.87 (TotallyNotJson.809):
|
procedure TotallyNotJson.87 (TotallyNotJson.809):
|
||||||
|
|
|
@ -247,8 +247,8 @@ procedure Str.9 (Str.79):
|
||||||
else
|
else
|
||||||
let Str.300 : U8 = StructAtIndex 3 Str.80;
|
let Str.300 : U8 = StructAtIndex 3 Str.80;
|
||||||
let Str.301 : U64 = StructAtIndex 0 Str.80;
|
let Str.301 : U64 = StructAtIndex 0 Str.80;
|
||||||
let #Derived_gen.1 : Str = StructAtIndex 1 Str.80;
|
let #Derived_gen.0 : Str = StructAtIndex 1 Str.80;
|
||||||
dec #Derived_gen.1;
|
dec #Derived_gen.0;
|
||||||
let Str.299 : {U64, U8} = Struct {Str.301, Str.300};
|
let Str.299 : {U64, U8} = Struct {Str.301, Str.300};
|
||||||
let Str.298 : [C {U64, U8}, C Str] = TagId(0) Str.299;
|
let Str.298 : [C {U64, U8}, C Str] = TagId(0) Str.299;
|
||||||
ret Str.298;
|
ret Str.298;
|
||||||
|
@ -365,8 +365,8 @@ procedure TotallyNotJson.534 (TotallyNotJson.535):
|
||||||
|
|
||||||
procedure TotallyNotJson.536 (TotallyNotJson.1192):
|
procedure TotallyNotJson.536 (TotallyNotJson.1192):
|
||||||
let TotallyNotJson.1193 : List U8 = StructAtIndex 1 TotallyNotJson.1192;
|
let TotallyNotJson.1193 : List U8 = StructAtIndex 1 TotallyNotJson.1192;
|
||||||
let #Derived_gen.0 : List U8 = StructAtIndex 0 TotallyNotJson.1192;
|
let #Derived_gen.1 : List U8 = StructAtIndex 0 TotallyNotJson.1192;
|
||||||
dec #Derived_gen.0;
|
dec #Derived_gen.1;
|
||||||
ret TotallyNotJson.1193;
|
ret TotallyNotJson.1193;
|
||||||
|
|
||||||
procedure TotallyNotJson.60 ():
|
procedure TotallyNotJson.60 ():
|
||||||
|
|
|
@ -248,8 +248,8 @@ procedure Str.9 (Str.79):
|
||||||
else
|
else
|
||||||
let Str.314 : U8 = StructAtIndex 3 Str.80;
|
let Str.314 : U8 = StructAtIndex 3 Str.80;
|
||||||
let Str.315 : U64 = StructAtIndex 0 Str.80;
|
let Str.315 : U64 = StructAtIndex 0 Str.80;
|
||||||
let #Derived_gen.1 : Str = StructAtIndex 1 Str.80;
|
let #Derived_gen.0 : Str = StructAtIndex 1 Str.80;
|
||||||
dec #Derived_gen.1;
|
dec #Derived_gen.0;
|
||||||
let Str.313 : {U64, U8} = Struct {Str.315, Str.314};
|
let Str.313 : {U64, U8} = Struct {Str.315, Str.314};
|
||||||
let Str.312 : [C {U64, U8}, C Str] = TagId(0) Str.313;
|
let Str.312 : [C {U64, U8}, C Str] = TagId(0) Str.313;
|
||||||
ret Str.312;
|
ret Str.312;
|
||||||
|
@ -397,8 +397,8 @@ procedure TotallyNotJson.534 (TotallyNotJson.535):
|
||||||
|
|
||||||
procedure TotallyNotJson.536 (TotallyNotJson.1192):
|
procedure TotallyNotJson.536 (TotallyNotJson.1192):
|
||||||
let TotallyNotJson.1193 : List U8 = StructAtIndex 1 TotallyNotJson.1192;
|
let TotallyNotJson.1193 : List U8 = StructAtIndex 1 TotallyNotJson.1192;
|
||||||
let #Derived_gen.0 : List U8 = StructAtIndex 0 TotallyNotJson.1192;
|
let #Derived_gen.1 : List U8 = StructAtIndex 0 TotallyNotJson.1192;
|
||||||
dec #Derived_gen.0;
|
dec #Derived_gen.1;
|
||||||
ret TotallyNotJson.1193;
|
ret TotallyNotJson.1193;
|
||||||
|
|
||||||
procedure TotallyNotJson.60 ():
|
procedure TotallyNotJson.60 ():
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
procedure Test.1 (Test.4):
|
procedure Test.1 (Test.4):
|
||||||
ret Test.4;
|
let Test.13 : [C Str, C Str] = TagId(0) Test.4;
|
||||||
|
ret Test.13;
|
||||||
|
|
||||||
procedure Test.5 (Test.12, Test.4):
|
procedure Test.1 (Test.4):
|
||||||
|
let Test.18 : [C Str, C Str] = TagId(0) Test.4;
|
||||||
|
ret Test.18;
|
||||||
|
|
||||||
|
procedure Test.5 (Test.12, #Attr.12):
|
||||||
|
let Test.4 : Str = UnionAtIndex (Id 0) (Index 0) #Attr.12;
|
||||||
dec Test.4;
|
dec Test.4;
|
||||||
let Test.14 : Str = "";
|
let Test.14 : Str = "";
|
||||||
ret Test.14;
|
ret Test.14;
|
||||||
|
@ -11,13 +17,13 @@ procedure Test.0 ():
|
||||||
joinpoint Test.9 Test.3:
|
joinpoint Test.9 Test.3:
|
||||||
ret Test.3;
|
ret Test.3;
|
||||||
in
|
in
|
||||||
let Test.19 : Int1 = true;
|
let Test.20 : Int1 = true;
|
||||||
let Test.20 : Int1 = lowlevel Eq Test.19 Test.2;
|
let Test.21 : Int1 = lowlevel Eq Test.20 Test.2;
|
||||||
if Test.20 then
|
if Test.21 then
|
||||||
let Test.15 : Str = "";
|
let Test.15 : Str = "";
|
||||||
let Test.10 : Str = CallByName Test.1 Test.15;
|
let Test.10 : [C Str, C Str] = CallByName Test.1 Test.15;
|
||||||
jump Test.9 Test.10;
|
jump Test.9 Test.10;
|
||||||
else
|
else
|
||||||
let Test.18 : Str = "";
|
let Test.19 : Str = "";
|
||||||
let Test.16 : Str = CallByName Test.1 Test.18;
|
let Test.16 : [C Str, C Str] = CallByName Test.1 Test.19;
|
||||||
jump Test.9 Test.16;
|
jump Test.9 Test.16;
|
||||||
|
|
|
@ -1854,8 +1854,7 @@ fn instantiate_annotated_as_recursive_alias_multiple_polymorphic_expr() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[mono_test]
|
#[mono_test(large_stack = "true")]
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
fn encode_derived_record_one_field_string() {
|
fn encode_derived_record_one_field_string() {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
|
@ -1872,8 +1871,7 @@ fn encode_derived_record_one_field_string() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[mono_test]
|
#[mono_test(large_stack = "true")]
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
fn encode_derived_record_two_field_strings() {
|
fn encode_derived_record_two_field_strings() {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
|
@ -1890,8 +1888,7 @@ fn encode_derived_record_two_field_strings() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[mono_test]
|
#[mono_test(large_stack = "true")]
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
fn encode_derived_nested_record_string() {
|
fn encode_derived_nested_record_string() {
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
|
@ -3078,3 +3075,16 @@ fn record_update() {
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[mono_test(mode = "test")]
|
||||||
|
fn dbg_in_expect() {
|
||||||
|
indoc!(
|
||||||
|
r###"
|
||||||
|
interface Test exposes [] imports []
|
||||||
|
|
||||||
|
expect
|
||||||
|
dbg ""
|
||||||
|
Bool.true
|
||||||
|
"###
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ pub fn mono_test(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
let mut no_check = false;
|
let mut no_check = false;
|
||||||
let mut allow_type_errors = false;
|
let mut allow_type_errors = false;
|
||||||
let mut mode = "exec".to_owned();
|
let mut mode = "exec".to_owned();
|
||||||
|
let mut large_stack = false;
|
||||||
for arg in syn::parse_macro_input!(args as syn::AttributeArgs) {
|
for arg in syn::parse_macro_input!(args as syn::AttributeArgs) {
|
||||||
use syn::{Lit, Meta, MetaNameValue, NestedMeta};
|
use syn::{Lit, Meta, MetaNameValue, NestedMeta};
|
||||||
if let NestedMeta::Meta(Meta::NameValue(MetaNameValue {
|
if let NestedMeta::Meta(Meta::NameValue(MetaNameValue {
|
||||||
|
@ -26,6 +27,9 @@ pub fn mono_test(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
if path.is_ident("allow_type_errors") {
|
if path.is_ident("allow_type_errors") {
|
||||||
allow_type_errors = true;
|
allow_type_errors = true;
|
||||||
}
|
}
|
||||||
|
if path.is_ident("large_stack") {
|
||||||
|
large_stack = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +48,11 @@ pub fn mono_test(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
#[test]
|
#[test]
|
||||||
#(#attributes)*
|
#(#attributes)*
|
||||||
#visibility fn #name(#args) {
|
#visibility fn #name(#args) {
|
||||||
compiles_to_ir(#name_str, #body, &#mode, #allow_type_errors, #no_check);
|
if #large_stack {
|
||||||
|
with_larger_debug_stack(|| compiles_to_ir(#name_str, #body, &#mode, #allow_type_errors, #no_check));
|
||||||
|
} else {
|
||||||
|
compiles_to_ir(#name_str, #body, &#mode, #allow_type_errors, #no_check);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
result.into()
|
result.into()
|
||||||
|
|
|
@ -416,9 +416,10 @@ pub fn load_types(
|
||||||
|
|
||||||
let layout = layout_cache.interner.get(in_layout);
|
let layout = layout_cache.interner.get(in_layout);
|
||||||
|
|
||||||
// dbg!(layout);
|
if layout_cache
|
||||||
|
.interner
|
||||||
if layout.has_varying_stack_size(&layout_cache.interner, arena) {
|
.has_varying_stack_size(in_layout, arena)
|
||||||
|
{
|
||||||
let ident_ids = interns.all_ident_ids.get_mut(&home).unwrap();
|
let ident_ids = interns.all_ident_ids.get_mut(&home).unwrap();
|
||||||
let answer = generate_glue_procs(
|
let answer = generate_glue_procs(
|
||||||
home,
|
home,
|
||||||
|
|
|
@ -1383,28 +1383,26 @@ fn add_type_help<'a>(
|
||||||
|
|
||||||
add_tag_union(env, opt_name, tags, var, types, layout, Some(rec_root))
|
add_tag_union(env, opt_name, tags, var, types, layout, Some(rec_root))
|
||||||
}
|
}
|
||||||
Content::Structure(FlatType::Apply(symbol, _)) => {
|
Content::Structure(FlatType::Apply(symbol, _)) => match env.layout_cache.get_repr(layout) {
|
||||||
match env.layout_cache.get_in(layout).repr {
|
LayoutRepr::Builtin(builtin) => {
|
||||||
LayoutRepr::Builtin(builtin) => {
|
add_builtin_type(env, builtin, var, opt_name, types, layout)
|
||||||
add_builtin_type(env, builtin, var, opt_name, types, layout)
|
}
|
||||||
}
|
_ => {
|
||||||
_ => {
|
if symbol.is_builtin() {
|
||||||
if symbol.is_builtin() {
|
todo!(
|
||||||
todo!(
|
"Handle Apply for builtin symbol {:?} and layout {:?}",
|
||||||
"Handle Apply for builtin symbol {:?} and layout {:?}",
|
symbol,
|
||||||
symbol,
|
layout
|
||||||
layout
|
)
|
||||||
)
|
} else {
|
||||||
} else {
|
todo!(
|
||||||
todo!(
|
"Handle non-builtin Apply for symbol {:?} and layout {:?}",
|
||||||
"Handle non-builtin Apply for symbol {:?} and layout {:?}",
|
symbol,
|
||||||
symbol,
|
layout
|
||||||
layout
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
Content::Structure(FlatType::Func(args, closure_var, ret_var)) => {
|
Content::Structure(FlatType::Func(args, closure_var, ret_var)) => {
|
||||||
let is_toplevel = false; // or in any case, we cannot assume that we are
|
let is_toplevel = false; // or in any case, we cannot assume that we are
|
||||||
|
|
||||||
|
@ -1432,7 +1430,7 @@ fn add_type_help<'a>(
|
||||||
}
|
}
|
||||||
Content::Alias(name, alias_vars, real_var, _) => {
|
Content::Alias(name, alias_vars, real_var, _) => {
|
||||||
if name.is_builtin() {
|
if name.is_builtin() {
|
||||||
match env.layout_cache.get_in(layout).repr {
|
match env.layout_cache.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(builtin) => {
|
LayoutRepr::Builtin(builtin) => {
|
||||||
add_builtin_type(env, builtin, var, opt_name, types, layout)
|
add_builtin_type(env, builtin, var, opt_name, types, layout)
|
||||||
}
|
}
|
||||||
|
@ -1687,7 +1685,7 @@ fn add_builtin_type<'a>(
|
||||||
Alias(Symbol::DICT_DICT, _alias_variables, alias_var, AliasKind::Opaque),
|
Alias(Symbol::DICT_DICT, _alias_variables, alias_var, AliasKind::Opaque),
|
||||||
) => {
|
) => {
|
||||||
match (
|
match (
|
||||||
env.layout_cache.get_in(elem_layout).repr,
|
env.layout_cache.get_repr(elem_layout),
|
||||||
env.subs.get_content_without_compacting(*alias_var),
|
env.subs.get_content_without_compacting(*alias_var),
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
|
@ -1737,7 +1735,7 @@ fn add_builtin_type<'a>(
|
||||||
Alias(Symbol::SET_SET, _alias_vars, alias_var, AliasKind::Opaque),
|
Alias(Symbol::SET_SET, _alias_vars, alias_var, AliasKind::Opaque),
|
||||||
) => {
|
) => {
|
||||||
match (
|
match (
|
||||||
env.layout_cache.get_in(elem_layout).repr,
|
env.layout_cache.get_repr(elem_layout),
|
||||||
env.subs.get_content_without_compacting(*alias_var),
|
env.subs.get_content_without_compacting(*alias_var),
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
|
@ -1842,7 +1840,10 @@ where
|
||||||
let layout = env.layout_cache.interner.get(in_layout);
|
let layout = env.layout_cache.interner.get(in_layout);
|
||||||
let struct_fields = match env.glue_procs_by_layout.get(&layout) {
|
let struct_fields = match env.glue_procs_by_layout.get(&layout) {
|
||||||
Some(&glue_procs) => {
|
Some(&glue_procs) => {
|
||||||
debug_assert!(layout.has_varying_stack_size(&env.layout_cache.interner, arena));
|
debug_assert!(env
|
||||||
|
.layout_cache
|
||||||
|
.interner
|
||||||
|
.has_varying_stack_size(in_layout, arena));
|
||||||
|
|
||||||
let fields: Vec<(String, TypeId, Accessors)> = sortables
|
let fields: Vec<(String, TypeId, Accessors)> = sortables
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -1910,7 +1911,7 @@ fn tag_union_type_from_layout<'a>(
|
||||||
) -> RocTagUnion {
|
) -> RocTagUnion {
|
||||||
let subs = env.subs;
|
let subs = env.subs;
|
||||||
|
|
||||||
match env.layout_cache.get_in(layout).repr {
|
match env.layout_cache.get_repr(layout) {
|
||||||
_ if union_tags.is_newtype_wrapper(subs)
|
_ if union_tags.is_newtype_wrapper(subs)
|
||||||
&& matches!(
|
&& matches!(
|
||||||
subs.get_content_without_compacting(var),
|
subs.get_content_without_compacting(var),
|
||||||
|
@ -2228,7 +2229,9 @@ fn single_tag_payload_fields<'a, 'b>(
|
||||||
// anyway just so we have some warning in case that relationship somehow didn't hold!
|
// anyway just so we have some warning in case that relationship somehow didn't hold!
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
env.glue_procs_by_layout.get(&layout).is_some(),
|
env.glue_procs_by_layout.get(&layout).is_some(),
|
||||||
layout.has_varying_stack_size(&env.layout_cache.interner, env.arena)
|
env.layout_cache
|
||||||
|
.interner
|
||||||
|
.has_varying_stack_size(in_layout, env.arena)
|
||||||
);
|
);
|
||||||
|
|
||||||
let (tag_name, payload_vars) = single_tag_payload(union_tags, subs);
|
let (tag_name, payload_vars) = single_tag_payload(union_tags, subs);
|
||||||
|
@ -2309,7 +2312,7 @@ fn struct_fields_needed<I: IntoIterator<Item = Variable>>(env: &mut Env<'_>, var
|
||||||
vars.into_iter().fold(0, |count, var| {
|
vars.into_iter().fold(0, |count, var| {
|
||||||
let layout = env.layout_cache.from_var(arena, var, subs).unwrap();
|
let layout = env.layout_cache.from_var(arena, var, subs).unwrap();
|
||||||
|
|
||||||
if env.layout_cache.get_in(layout).is_dropped_because_empty() {
|
if env.layout_cache.get_repr(layout).is_dropped_because_empty() {
|
||||||
count
|
count
|
||||||
} else {
|
} else {
|
||||||
count + 1
|
count + 1
|
||||||
|
|
|
@ -353,7 +353,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let expr = match env.layout_cache.get_in(layout).repr {
|
let expr = match env.layout_cache.get_repr(layout) {
|
||||||
LayoutRepr::Builtin(Builtin::Bool) => {
|
LayoutRepr::Builtin(Builtin::Bool) => {
|
||||||
app.call_function(main_fn_name, |_mem: &A::Memory, num: bool| {
|
app.call_function(main_fn_name, |_mem: &A::Memory, num: bool| {
|
||||||
bool_to_ast(env, num, env.subs.get_content_without_compacting(raw_var))
|
bool_to_ast(env, num, env.subs.get_content_without_compacting(raw_var))
|
||||||
|
@ -475,7 +475,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
||||||
env,
|
env,
|
||||||
mem,
|
mem,
|
||||||
addr,
|
addr,
|
||||||
layout,
|
env.layout_cache.get_repr(layout),
|
||||||
WhenRecursive::Unreachable,
|
WhenRecursive::Unreachable,
|
||||||
env.subs.get_root_key_without_compacting(raw_var),
|
env.subs.get_root_key_without_compacting(raw_var),
|
||||||
)
|
)
|
||||||
|
@ -496,7 +496,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
||||||
env,
|
env,
|
||||||
mem,
|
mem,
|
||||||
addr,
|
addr,
|
||||||
layout,
|
env.layout_cache.get_repr(layout),
|
||||||
WhenRecursive::Loop(layout),
|
WhenRecursive::Loop(layout),
|
||||||
env.subs.get_root_key_without_compacting(raw_var),
|
env.subs.get_root_key_without_compacting(raw_var),
|
||||||
)
|
)
|
||||||
|
@ -515,7 +515,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
||||||
env,
|
env,
|
||||||
mem,
|
mem,
|
||||||
addr,
|
addr,
|
||||||
layout,
|
env.layout_cache.get_repr(layout),
|
||||||
WhenRecursive::Unreachable,
|
WhenRecursive::Unreachable,
|
||||||
env.subs.get_root_key_without_compacting(raw_var),
|
env.subs.get_root_key_without_compacting(raw_var),
|
||||||
)
|
)
|
||||||
|
@ -542,7 +542,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
mem: &'a M,
|
mem: &'a M,
|
||||||
addr: usize,
|
addr: usize,
|
||||||
layout: InLayout<'a>,
|
layout: LayoutRepr<'a>,
|
||||||
when_recursive: WhenRecursive<'a>,
|
when_recursive: WhenRecursive<'a>,
|
||||||
var: Variable,
|
var: Variable,
|
||||||
) -> Expr<'a> {
|
) -> Expr<'a> {
|
||||||
|
@ -557,7 +557,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
||||||
let (newtype_containers, _alias_content, raw_var) = unroll_newtypes_and_aliases(env, var);
|
let (newtype_containers, _alias_content, raw_var) = unroll_newtypes_and_aliases(env, var);
|
||||||
let raw_content = env.subs.get_content_without_compacting(raw_var);
|
let raw_content = env.subs.get_content_without_compacting(raw_var);
|
||||||
|
|
||||||
let expr = match (raw_content, env.layout_cache.get_in(layout).repr) {
|
let expr = match (raw_content, layout) {
|
||||||
(Content::Structure(FlatType::Func(_, _, _)), _) | (_, LayoutRepr::LambdaSet(_)) => {
|
(Content::Structure(FlatType::Func(_, _, _)), _) | (_, LayoutRepr::LambdaSet(_)) => {
|
||||||
OPAQUE_FUNCTION
|
OPAQUE_FUNCTION
|
||||||
}
|
}
|
||||||
|
@ -650,7 +650,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
||||||
},
|
},
|
||||||
WhenRecursive::Loop(union_layout),
|
WhenRecursive::Loop(union_layout),
|
||||||
) => {
|
) => {
|
||||||
addr_to_ast(env, mem, addr, union_layout, when_recursive, *structure)
|
addr_to_ast(env, mem, addr, env.layout_cache.get_repr(union_layout), when_recursive, *structure)
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
|
@ -665,9 +665,9 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
||||||
let union_layout = env.layout_cache
|
let union_layout = env.layout_cache
|
||||||
.from_var(env.arena, *structure, env.subs)
|
.from_var(env.arena, *structure, env.subs)
|
||||||
.expect("no layout for structure");
|
.expect("no layout for structure");
|
||||||
debug_assert!(matches!(env.layout_cache.get_in(union_layout).repr, LayoutRepr::Union(..)));
|
debug_assert!(matches!(env.layout_cache.get_repr(union_layout), LayoutRepr::Union(..)));
|
||||||
let when_recursive = WhenRecursive::Loop(union_layout);
|
let when_recursive = WhenRecursive::Loop(union_layout);
|
||||||
addr_to_ast(env, mem, addr, union_layout, when_recursive, *structure)
|
addr_to_ast(env, mem, addr, env.layout_cache.get_repr(union_layout), when_recursive, *structure)
|
||||||
}
|
}
|
||||||
other => unreachable!("Something had a RecursivePointer layout, but instead of being a RecursionVar and having a known recursive layout, I found {:?}", other),
|
other => unreachable!("Something had a RecursivePointer layout, but instead of being a RecursionVar and having a known recursive layout, I found {:?}", other),
|
||||||
},
|
},
|
||||||
|
@ -873,7 +873,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
||||||
env,
|
env,
|
||||||
mem,
|
mem,
|
||||||
addr_of_inner,
|
addr_of_inner,
|
||||||
inner_layout,
|
env.layout_cache.get_repr(inner_layout),
|
||||||
WhenRecursive::Unreachable,
|
WhenRecursive::Unreachable,
|
||||||
inner_var,
|
inner_var,
|
||||||
);
|
);
|
||||||
|
@ -930,7 +930,7 @@ fn list_to_ast<'a, M: ReplAppMemory>(
|
||||||
env,
|
env,
|
||||||
mem,
|
mem,
|
||||||
elem_addr,
|
elem_addr,
|
||||||
elem_layout,
|
env.layout_cache.get_repr(elem_layout),
|
||||||
WhenRecursive::Unreachable,
|
WhenRecursive::Unreachable,
|
||||||
elem_content,
|
elem_content,
|
||||||
);
|
);
|
||||||
|
@ -993,7 +993,14 @@ where
|
||||||
let mut field_addr = addr;
|
let mut field_addr = addr;
|
||||||
|
|
||||||
for (var, layout) in sequence {
|
for (var, layout) in sequence {
|
||||||
let expr = addr_to_ast(env, mem, field_addr, *layout, when_recursive, var);
|
let expr = addr_to_ast(
|
||||||
|
env,
|
||||||
|
mem,
|
||||||
|
field_addr,
|
||||||
|
env.layout_cache.get_repr(*layout),
|
||||||
|
when_recursive,
|
||||||
|
var,
|
||||||
|
);
|
||||||
let loc_expr = Loc::at_zero(expr);
|
let loc_expr = Loc::at_zero(expr);
|
||||||
|
|
||||||
output.push(&*arena.alloc(loc_expr));
|
output.push(&*arena.alloc(loc_expr));
|
||||||
|
@ -1029,9 +1036,7 @@ fn struct_to_ast<'a, M: ReplAppMemory>(
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let inner_layouts = arena.alloc([field_layout]);
|
let inner_layouts = arena.alloc([field_layout]);
|
||||||
|
|
||||||
let struct_layout = env
|
let struct_layout = LayoutRepr::struct_(inner_layouts);
|
||||||
.layout_cache
|
|
||||||
.put_in_no_semantic(LayoutRepr::struct_(inner_layouts));
|
|
||||||
let loc_expr = &*arena.alloc(Loc {
|
let loc_expr = &*arena.alloc(Loc {
|
||||||
value: addr_to_ast(
|
value: addr_to_ast(
|
||||||
env,
|
env,
|
||||||
|
@ -1094,7 +1099,7 @@ fn struct_to_ast<'a, M: ReplAppMemory>(
|
||||||
env,
|
env,
|
||||||
mem,
|
mem,
|
||||||
field_addr,
|
field_addr,
|
||||||
field_layout,
|
env.layout_cache.get_repr(field_layout),
|
||||||
WhenRecursive::Unreachable,
|
WhenRecursive::Unreachable,
|
||||||
field_var,
|
field_var,
|
||||||
),
|
),
|
||||||
|
@ -1175,7 +1180,7 @@ fn struct_to_ast_tuple<'a, M: ReplAppMemory>(
|
||||||
env,
|
env,
|
||||||
mem,
|
mem,
|
||||||
field_addr,
|
field_addr,
|
||||||
elem_layout,
|
env.layout_cache.get_repr(elem_layout),
|
||||||
WhenRecursive::Unreachable,
|
WhenRecursive::Unreachable,
|
||||||
elem_var,
|
elem_var,
|
||||||
),
|
),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue