add ptr_bytes to layout env

This commit is contained in:
Folkert 2021-08-26 22:12:44 +02:00
parent af1051ef89
commit a070a7fcc7
3 changed files with 56 additions and 33 deletions

View file

@ -222,7 +222,8 @@ fn jit_to_ast_help<'a>(
let tags_map: roc_collections::all::MutMap<_, _> = let tags_map: roc_collections::all::MutMap<_, _> =
tags_vec.iter().cloned().collect(); tags_vec.iter().cloned().collect();
let union_variant = union_sorted_tags_help(env.arena, tags_vec, None, env.subs); let union_variant =
union_sorted_tags_help(env.arena, tags_vec, None, env.subs, env.ptr_bytes);
let size = layout.stack_size(env.ptr_bytes); let size = layout.stack_size(env.ptr_bytes);
use roc_mono::layout::WrappedVariant::*; use roc_mono::layout::WrappedVariant::*;
@ -886,7 +887,8 @@ fn byte_to_ast<'a>(env: &Env<'a, '_>, value: u8, content: &Content) -> Expr<'a>
.map(|(a, b)| (a.clone(), b.to_vec())) .map(|(a, b)| (a.clone(), b.to_vec()))
.collect(); .collect();
let union_variant = union_sorted_tags_help(env.arena, tags_vec, None, env.subs); let union_variant =
union_sorted_tags_help(env.arena, tags_vec, None, env.subs, env.ptr_bytes);
match union_variant { match union_variant {
UnionVariant::ByteUnion(tagnames) => { UnionVariant::ByteUnion(tagnames) => {

View file

@ -3109,7 +3109,8 @@ pub fn with_hole<'a>(
mut fields, mut fields,
.. ..
} => { } => {
let sorted_fields = crate::layout::sort_record_fields(env.arena, record_var, env.subs); let sorted_fields =
crate::layout::sort_record_fields(env.arena, record_var, env.subs, env.ptr_bytes);
let mut field_symbols = Vec::with_capacity_in(fields.len(), env.arena); let mut field_symbols = Vec::with_capacity_in(fields.len(), env.arena);
let mut can_fields = Vec::with_capacity_in(fields.len(), env.arena); let mut can_fields = Vec::with_capacity_in(fields.len(), env.arena);
@ -3444,7 +3445,8 @@ pub fn with_hole<'a>(
loc_expr, loc_expr,
.. ..
} => { } => {
let sorted_fields = crate::layout::sort_record_fields(env.arena, record_var, env.subs); let sorted_fields =
crate::layout::sort_record_fields(env.arena, record_var, env.subs, env.ptr_bytes);
let mut index = None; let mut index = None;
let mut field_layouts = Vec::with_capacity_in(sorted_fields.len(), env.arena); let mut field_layouts = Vec::with_capacity_in(sorted_fields.len(), env.arena);
@ -3586,7 +3588,8 @@ pub fn with_hole<'a>(
// This has the benefit that we don't need to do anything special for reference // This has the benefit that we don't need to do anything special for reference
// counting // counting
let sorted_fields = crate::layout::sort_record_fields(env.arena, record_var, env.subs); let sorted_fields =
crate::layout::sort_record_fields(env.arena, record_var, env.subs, env.ptr_bytes);
let mut field_layouts = Vec::with_capacity_in(sorted_fields.len(), env.arena); let mut field_layouts = Vec::with_capacity_in(sorted_fields.len(), env.arena);
@ -4190,7 +4193,8 @@ fn convert_tag_union<'a>(
arena: &'a Bump, arena: &'a Bump,
) -> Stmt<'a> { ) -> Stmt<'a> {
use crate::layout::UnionVariant::*; use crate::layout::UnionVariant::*;
let res_variant = crate::layout::union_sorted_tags(env.arena, variant_var, env.subs); let res_variant =
crate::layout::union_sorted_tags(env.arena, variant_var, env.subs, env.ptr_bytes);
let variant = match res_variant { let variant = match res_variant {
Ok(cached) => cached, Ok(cached) => cached,
Err(LayoutProblem::UnresolvedTypeVar(_)) => { Err(LayoutProblem::UnresolvedTypeVar(_)) => {
@ -6934,7 +6938,8 @@ fn from_can_pattern_help<'a>(
use crate::exhaustive::Union; use crate::exhaustive::Union;
use crate::layout::UnionVariant::*; use crate::layout::UnionVariant::*;
let res_variant = crate::layout::union_sorted_tags(env.arena, *whole_var, env.subs); let res_variant =
crate::layout::union_sorted_tags(env.arena, *whole_var, env.subs, env.ptr_bytes);
let variant = match res_variant { let variant = match res_variant {
Ok(cached) => cached, Ok(cached) => cached,
@ -7353,7 +7358,8 @@ fn from_can_pattern_help<'a>(
.. ..
} => { } => {
// sorted fields based on the type // sorted fields based on the type
let sorted_fields = crate::layout::sort_record_fields(env.arena, *whole_var, env.subs); let sorted_fields =
crate::layout::sort_record_fields(env.arena, *whole_var, env.subs, env.ptr_bytes);
// sorted fields based on the destruct // sorted fields based on the destruct
let mut mono_destructs = Vec::with_capacity_in(destructs.len(), env.arena); let mut mono_destructs = Vec::with_capacity_in(destructs.len(), env.arena);

View file

@ -138,7 +138,8 @@ impl<'a> RawFunctionLayout<'a> {
let fn_args = fn_args.into_bump_slice(); let fn_args = fn_args.into_bump_slice();
let ret = arena.alloc(ret); let ret = arena.alloc(ret);
let lambda_set = LambdaSet::from_var(env.arena, env.subs, closure_var)?; let lambda_set =
LambdaSet::from_var(env.arena, env.subs, closure_var, env.ptr_bytes)?;
Ok(Self::Function(fn_args, lambda_set, ret)) Ok(Self::Function(fn_args, lambda_set, ret))
} }
@ -516,6 +517,7 @@ impl<'a> LambdaSet<'a> {
arena: &'a Bump, arena: &'a Bump,
subs: &Subs, subs: &Subs,
closure_var: Variable, closure_var: Variable,
ptr_bytes: u32,
) -> Result<Self, LayoutProblem> { ) -> Result<Self, LayoutProblem> {
let mut tags = std::vec::Vec::new(); let mut tags = std::vec::Vec::new();
match roc_types::pretty_print::chase_ext_tag_union(subs, closure_var, &mut tags) { match roc_types::pretty_print::chase_ext_tag_union(subs, closure_var, &mut tags) {
@ -529,6 +531,7 @@ impl<'a> LambdaSet<'a> {
arena, arena,
subs, subs,
seen: Vec::new_in(arena), seen: Vec::new_in(arena),
ptr_bytes,
}; };
for (tag_name, variables) in tags.iter() { for (tag_name, variables) in tags.iter() {
@ -545,7 +548,8 @@ impl<'a> LambdaSet<'a> {
} }
} }
let representation = arena.alloc(Self::make_representation(arena, subs, tags)); let representation =
arena.alloc(Self::make_representation(arena, subs, tags, ptr_bytes));
Ok(LambdaSet { Ok(LambdaSet {
set: set.into_bump_slice(), set: set.into_bump_slice(),
@ -568,9 +572,10 @@ impl<'a> LambdaSet<'a> {
arena: &'a Bump, arena: &'a Bump,
subs: &Subs, subs: &Subs,
tags: std::vec::Vec<(TagName, std::vec::Vec<Variable>)>, tags: std::vec::Vec<(TagName, std::vec::Vec<Variable>)>,
ptr_bytes: u32,
) -> Layout<'a> { ) -> Layout<'a> {
// otherwise, this is a closure with a payload // otherwise, this is a closure with a payload
let variant = union_sorted_tags_help(arena, tags, None, subs); let variant = union_sorted_tags_help(arena, tags, None, subs, ptr_bytes);
use UnionVariant::*; use UnionVariant::*;
match variant { match variant {
@ -648,6 +653,7 @@ pub enum Builtin<'a> {
} }
pub struct Env<'a, 'b> { pub struct Env<'a, 'b> {
ptr_bytes: u32,
arena: &'a Bump, arena: &'a Bump,
seen: Vec<'a, Variable>, seen: Vec<'a, Variable>,
subs: &'b Subs, subs: &'b Subs,
@ -1006,6 +1012,7 @@ impl<'a> LayoutCache<'a> {
arena, arena,
subs, subs,
seen: Vec::new_in(arena), seen: Vec::new_in(arena),
ptr_bytes: self.ptr_bytes,
}; };
Layout::from_var(&mut env, var) Layout::from_var(&mut env, var)
@ -1024,6 +1031,7 @@ impl<'a> LayoutCache<'a> {
arena, arena,
subs, subs,
seen: Vec::new_in(arena), seen: Vec::new_in(arena),
ptr_bytes: self.ptr_bytes,
}; };
RawFunctionLayout::from_var(&mut env, var) RawFunctionLayout::from_var(&mut env, var)
@ -1190,6 +1198,7 @@ fn layout_from_flat_type<'a>(
let arena = env.arena; let arena = env.arena;
let subs = env.subs; let subs = env.subs;
let ptr_bytes = env.ptr_bytes;
match flat_type { match flat_type {
Apply(symbol, args) => { Apply(symbol, args) => {
@ -1281,7 +1290,7 @@ fn layout_from_flat_type<'a>(
} }
} }
Func(_, closure_var, _) => { Func(_, closure_var, _) => {
let lambda_set = LambdaSet::from_var(env.arena, env.subs, closure_var)?; let lambda_set = LambdaSet::from_var(env.arena, env.subs, closure_var, env.ptr_bytes)?;
Ok(lambda_set.runtime_representation()) Ok(lambda_set.runtime_representation())
} }
@ -1307,8 +1316,6 @@ fn layout_from_flat_type<'a>(
let mut pairs = Vec::from_iter_in(pairs_it, arena); let mut pairs = Vec::from_iter_in(pairs_it, arena);
pairs.sort_by(|(label1, layout1), (label2, layout2)| { pairs.sort_by(|(label1, layout1), (label2, layout2)| {
let ptr_bytes = 8;
let size1 = layout1.alignment_bytes(ptr_bytes); let size1 = layout1.alignment_bytes(ptr_bytes);
let size2 = layout2.alignment_bytes(ptr_bytes); let size2 = layout2.alignment_bytes(ptr_bytes);
@ -1328,14 +1335,14 @@ fn layout_from_flat_type<'a>(
TagUnion(tags, ext_var) => { TagUnion(tags, ext_var) => {
debug_assert!(ext_var_is_empty_tag_union(subs, ext_var)); debug_assert!(ext_var_is_empty_tag_union(subs, ext_var));
Ok(layout_from_tag_union(arena, tags, subs)) Ok(layout_from_tag_union(arena, tags, subs, env.ptr_bytes))
} }
FunctionOrTagUnion(tag_name, _, ext_var) => { FunctionOrTagUnion(tag_name, _, ext_var) => {
debug_assert!(ext_var_is_empty_tag_union(subs, ext_var)); debug_assert!(ext_var_is_empty_tag_union(subs, ext_var));
let tags = UnionTags::from_tag_name_index(tag_name); let tags = UnionTags::from_tag_name_index(tag_name);
Ok(layout_from_tag_union(arena, tags, subs)) Ok(layout_from_tag_union(arena, tags, subs, env.ptr_bytes))
} }
RecursiveTagUnion(rec_var, tags, ext_var) => { RecursiveTagUnion(rec_var, tags, ext_var) => {
debug_assert!(ext_var_is_empty_tag_union(subs, ext_var)); debug_assert!(ext_var_is_empty_tag_union(subs, ext_var));
@ -1385,8 +1392,6 @@ fn layout_from_flat_type<'a>(
} }
tag_layout.sort_by(|layout1, layout2| { tag_layout.sort_by(|layout1, layout2| {
let ptr_bytes = 8;
let size1 = layout1.alignment_bytes(ptr_bytes); let size1 = layout1.alignment_bytes(ptr_bytes);
let size2 = layout2.alignment_bytes(ptr_bytes); let size2 = layout2.alignment_bytes(ptr_bytes);
@ -1433,11 +1438,13 @@ pub fn sort_record_fields<'a>(
arena: &'a Bump, arena: &'a Bump,
var: Variable, var: Variable,
subs: &Subs, subs: &Subs,
ptr_bytes: u32,
) -> Vec<'a, (Lowercase, Variable, Result<Layout<'a>, Layout<'a>>)> { ) -> Vec<'a, (Lowercase, Variable, Result<Layout<'a>, Layout<'a>>)> {
let mut env = Env { let mut env = Env {
arena, arena,
subs, subs,
seen: Vec::new_in(arena), seen: Vec::new_in(arena),
ptr_bytes,
}; };
let (it, _) = gather_fields_unsorted_iter(subs, RecordFields::empty(), var); let (it, _) = gather_fields_unsorted_iter(subs, RecordFields::empty(), var);
@ -1453,6 +1460,8 @@ fn sort_record_fields_help<'a>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
fields_map: impl Iterator<Item = (Lowercase, RecordField<Variable>)>, fields_map: impl Iterator<Item = (Lowercase, RecordField<Variable>)>,
) -> Vec<'a, (Lowercase, Variable, Result<Layout<'a>, Layout<'a>>)> { ) -> Vec<'a, (Lowercase, Variable, Result<Layout<'a>, Layout<'a>>)> {
let ptr_bytes = env.ptr_bytes;
// Sort the fields by label // Sort the fields by label
let mut sorted_fields = Vec::with_capacity_in(fields_map.size_hint().0, env.arena); let mut sorted_fields = Vec::with_capacity_in(fields_map.size_hint().0, env.arena);
@ -1476,8 +1485,6 @@ fn sort_record_fields_help<'a>(
|(label1, _, res_layout1), (label2, _, res_layout2)| match res_layout1 { |(label1, _, res_layout1), (label2, _, res_layout2)| match res_layout1 {
Ok(layout1) | Err(layout1) => match res_layout2 { Ok(layout1) | Err(layout1) => match res_layout2 {
Ok(layout2) | Err(layout2) => { Ok(layout2) | Err(layout2) => {
let ptr_bytes = 8;
let size1 = layout1.alignment_bytes(ptr_bytes); let size1 = layout1.alignment_bytes(ptr_bytes);
let size2 = layout2.alignment_bytes(ptr_bytes); let size2 = layout2.alignment_bytes(ptr_bytes);
@ -1613,6 +1620,7 @@ pub fn union_sorted_tags<'a>(
arena: &'a Bump, arena: &'a Bump,
var: Variable, var: Variable,
subs: &Subs, subs: &Subs,
ptr_bytes: u32,
) -> Result<UnionVariant<'a>, LayoutProblem> { ) -> Result<UnionVariant<'a>, LayoutProblem> {
let var = let var =
if let Content::RecursionVar { structure, .. } = subs.get_content_without_compacting(var) { if let Content::RecursionVar { structure, .. } = subs.get_content_without_compacting(var) {
@ -1625,7 +1633,7 @@ pub fn union_sorted_tags<'a>(
let result = match roc_types::pretty_print::chase_ext_tag_union(subs, var, &mut tags_vec) { let result = match roc_types::pretty_print::chase_ext_tag_union(subs, var, &mut tags_vec) {
Ok(()) | Err((_, Content::FlexVar(_))) | Err((_, Content::RecursionVar { .. })) => { Ok(()) | Err((_, Content::FlexVar(_))) | Err((_, Content::RecursionVar { .. })) => {
let opt_rec_var = get_recursion_var(subs, var); let opt_rec_var = get_recursion_var(subs, var);
union_sorted_tags_help(arena, tags_vec, opt_rec_var, subs) union_sorted_tags_help(arena, tags_vec, opt_rec_var, subs, ptr_bytes)
} }
Err((_, Content::Error)) => return Err(LayoutProblem::Erroneous), Err((_, Content::Error)) => return Err(LayoutProblem::Erroneous),
Err(other) => panic!("invalid content in tag union variable: {:?}", other), Err(other) => panic!("invalid content in tag union variable: {:?}", other),
@ -1659,6 +1667,7 @@ fn union_sorted_tags_help_new<'a>(
mut tags_vec: Vec<(&'_ TagName, VariableSubsSlice)>, mut tags_vec: Vec<(&'_ TagName, VariableSubsSlice)>,
opt_rec_var: Option<Variable>, opt_rec_var: Option<Variable>,
subs: &Subs, subs: &Subs,
ptr_bytes: u32,
) -> UnionVariant<'a> { ) -> UnionVariant<'a> {
// sort up front; make sure the ordering stays intact! // sort up front; make sure the ordering stays intact!
tags_vec.sort_unstable_by(|(a, _), (b, _)| a.cmp(b)); tags_vec.sort_unstable_by(|(a, _), (b, _)| a.cmp(b));
@ -1667,6 +1676,7 @@ fn union_sorted_tags_help_new<'a>(
arena, arena,
subs, subs,
seen: Vec::new_in(arena), seen: Vec::new_in(arena),
ptr_bytes,
}; };
match tags_vec.len() { match tags_vec.len() {
@ -1716,8 +1726,6 @@ fn union_sorted_tags_help_new<'a>(
} }
layouts.sort_by(|layout1, layout2| { layouts.sort_by(|layout1, layout2| {
let ptr_bytes = 8;
let size1 = layout1.alignment_bytes(ptr_bytes); let size1 = layout1.alignment_bytes(ptr_bytes);
let size2 = layout2.alignment_bytes(ptr_bytes); let size2 = layout2.alignment_bytes(ptr_bytes);
@ -1801,8 +1809,6 @@ fn union_sorted_tags_help_new<'a>(
} }
arg_layouts.sort_by(|layout1, layout2| { arg_layouts.sort_by(|layout1, layout2| {
let ptr_bytes = 8;
let size1 = layout1.alignment_bytes(ptr_bytes); let size1 = layout1.alignment_bytes(ptr_bytes);
let size2 = layout2.alignment_bytes(ptr_bytes); let size2 = layout2.alignment_bytes(ptr_bytes);
@ -1875,6 +1881,7 @@ pub fn union_sorted_tags_help<'a>(
mut tags_vec: std::vec::Vec<(TagName, std::vec::Vec<Variable>)>, mut tags_vec: std::vec::Vec<(TagName, std::vec::Vec<Variable>)>,
opt_rec_var: Option<Variable>, opt_rec_var: Option<Variable>,
subs: &Subs, subs: &Subs,
ptr_bytes: u32,
) -> UnionVariant<'a> { ) -> UnionVariant<'a> {
// sort up front; make sure the ordering stays intact! // sort up front; make sure the ordering stays intact!
tags_vec.sort_unstable_by(|(a, _), (b, _)| a.cmp(b)); tags_vec.sort_unstable_by(|(a, _), (b, _)| a.cmp(b));
@ -1883,6 +1890,7 @@ pub fn union_sorted_tags_help<'a>(
arena, arena,
subs, subs,
seen: Vec::new_in(arena), seen: Vec::new_in(arena),
ptr_bytes,
}; };
match tags_vec.len() { match tags_vec.len() {
@ -1929,8 +1937,6 @@ pub fn union_sorted_tags_help<'a>(
} }
layouts.sort_by(|layout1, layout2| { layouts.sort_by(|layout1, layout2| {
let ptr_bytes = 8;
let size1 = layout1.alignment_bytes(ptr_bytes); let size1 = layout1.alignment_bytes(ptr_bytes);
let size2 = layout2.alignment_bytes(ptr_bytes); let size2 = layout2.alignment_bytes(ptr_bytes);
@ -2013,8 +2019,6 @@ pub fn union_sorted_tags_help<'a>(
} }
arg_layouts.sort_by(|layout1, layout2| { arg_layouts.sort_by(|layout1, layout2| {
let ptr_bytes = 8;
let size1 = layout1.alignment_bytes(ptr_bytes); let size1 = layout1.alignment_bytes(ptr_bytes);
let size2 = layout2.alignment_bytes(ptr_bytes); let size2 = layout2.alignment_bytes(ptr_bytes);
@ -2099,7 +2103,12 @@ fn cheap_sort_tags<'a, 'b>(
tags_vec tags_vec
} }
fn layout_from_newtype<'a>(arena: &'a Bump, tags: UnionTags, subs: &Subs) -> Layout<'a> { fn layout_from_newtype<'a>(
arena: &'a Bump,
tags: UnionTags,
subs: &Subs,
ptr_bytes: u32,
) -> Layout<'a> {
debug_assert!(tags.is_newtype_wrapper(subs)); debug_assert!(tags.is_newtype_wrapper(subs));
let slice_index = tags.variables().into_iter().next().unwrap(); let slice_index = tags.variables().into_iter().next().unwrap();
@ -2117,6 +2126,7 @@ fn layout_from_newtype<'a>(arena: &'a Bump, tags: UnionTags, subs: &Subs) -> Lay
arena, arena,
subs, subs,
seen: Vec::new_in(arena), seen: Vec::new_in(arena),
ptr_bytes,
}; };
match Layout::from_var(&mut env, var) { match Layout::from_var(&mut env, var) {
@ -2136,11 +2146,16 @@ fn layout_from_newtype<'a>(arena: &'a Bump, tags: UnionTags, subs: &Subs) -> Lay
} }
} }
fn layout_from_tag_union<'a>(arena: &'a Bump, tags: UnionTags, subs: &Subs) -> Layout<'a> { fn layout_from_tag_union<'a>(
arena: &'a Bump,
tags: UnionTags,
subs: &Subs,
ptr_bytes: u32,
) -> Layout<'a> {
use UnionVariant::*; use UnionVariant::*;
if tags.is_newtype_wrapper(subs) { if tags.is_newtype_wrapper(subs) {
return layout_from_newtype(arena, tags, subs); return layout_from_newtype(arena, tags, subs, ptr_bytes);
} }
let tags_vec = cheap_sort_tags(arena, tags, subs); let tags_vec = cheap_sort_tags(arena, tags, subs);
@ -2156,7 +2171,7 @@ fn layout_from_tag_union<'a>(arena: &'a Bump, tags: UnionTags, subs: &Subs) -> L
} }
_ => { _ => {
let opt_rec_var = None; let opt_rec_var = None;
let variant = union_sorted_tags_help_new(arena, tags_vec, opt_rec_var, subs); let variant = union_sorted_tags_help_new(arena, tags_vec, opt_rec_var, subs, ptr_bytes);
match variant { match variant {
Never => Layout::Union(UnionLayout::NonRecursive(&[])), Never => Layout::Union(UnionLayout::NonRecursive(&[])),