mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
fix bug where incorrect stack size is given
This commit is contained in:
parent
c73c01aa34
commit
fd209f90ff
5 changed files with 93 additions and 41 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -1786,20 +1786,20 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inkwell"
|
name = "inkwell"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/rtfeldman/inkwell?branch=master#b3fb82c653ffe754e078ac778d7fd9a619a26c0c"
|
source = "git+https://github.com/rtfeldman/inkwell?branch=master#32aebaf0ee1110ad4f6eaa901fe58078a4cd8894"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"either",
|
||||||
"inkwell_internals",
|
"inkwell_internals",
|
||||||
"libc",
|
"libc",
|
||||||
"llvm-sys",
|
"llvm-sys",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot 0.11.2",
|
"parking_lot 0.12.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inkwell_internals"
|
name = "inkwell_internals"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "git+https://github.com/rtfeldman/inkwell?branch=master#b3fb82c653ffe754e078ac778d7fd9a619a26c0c"
|
source = "git+https://github.com/rtfeldman/inkwell?branch=master#32aebaf0ee1110ad4f6eaa901fe58078a4cd8894"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1996,9 +1996,9 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "llvm-sys"
|
name = "llvm-sys"
|
||||||
version = "120.2.1"
|
version = "120.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4a810627ac62b396f5fd2214ba9bbd8748d4d6efdc4d2c1c1303ea7a75763ce"
|
checksum = "ce76f8393b7a607a906087666db398d872db739622e644e58552c198ccdfdf45"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
|
|
@ -131,30 +131,28 @@ fn call_bitcode_fn_help<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let call = env.builder.build_call(fn_val, &arguments, "call_builtin");
|
let call = env.builder.build_call(fn_val, &arguments, "call_builtin");
|
||||||
|
|
||||||
|
for i in 0..fn_val.count_params() {
|
||||||
|
let attributes = fn_val.attributes(AttributeLoc::Param(i));
|
||||||
|
|
||||||
|
for attribute in attributes {
|
||||||
|
if attribute.is_type() {}
|
||||||
|
call.add_attribute(AttributeLoc::Param(i), attribute)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match fn_name {
|
match fn_name {
|
||||||
bitcode::STR_NUMBER_OF_BYTES | bitcode::STR_COUNT_GRAPEHEME_CLUSTERS => {
|
bitcode::STR_NUMBER_OF_BYTES | bitcode::STR_COUNT_GRAPEHEME_CLUSTERS => {
|
||||||
// hacks
|
string_argument(env, call, 0);
|
||||||
|
}
|
||||||
|
bitcode::STR_ENDS_WITH | bitcode::STR_STARTS_WITH => {
|
||||||
|
string_argument(env, call, 0);
|
||||||
|
string_argument(env, call, 1);
|
||||||
|
}
|
||||||
|
bitcode::STR_STR_SPLIT_IN_PLACE => {
|
||||||
|
string_argument(env, call, 0);
|
||||||
|
string_argument(env, call, 1);
|
||||||
|
|
||||||
let i = 0;
|
dbg!(fn_val.get_type());
|
||||||
call.add_attribute(
|
|
||||||
AttributeLoc::Param(0),
|
|
||||||
type_attribute(env.context, "byval", zig_str_type(env).into()),
|
|
||||||
);
|
|
||||||
|
|
||||||
call.add_attribute(
|
|
||||||
AttributeLoc::Param(i as u32),
|
|
||||||
enum_attribute(env.context, "nonnull"),
|
|
||||||
);
|
|
||||||
|
|
||||||
call.add_attribute(
|
|
||||||
AttributeLoc::Param(i as u32),
|
|
||||||
enum_attribute(env.context, "nocapture"),
|
|
||||||
);
|
|
||||||
|
|
||||||
call.add_attribute(
|
|
||||||
AttributeLoc::Param(i as u32),
|
|
||||||
enum_attribute(env.context, "readonly"),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -163,6 +161,32 @@ fn call_bitcode_fn_help<'a, 'ctx, 'env>(
|
||||||
call
|
call
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn string_argument<'a, 'ctx, 'env>(
|
||||||
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
call: CallSiteValue,
|
||||||
|
parameter_index: u32,
|
||||||
|
) {
|
||||||
|
call.add_attribute(
|
||||||
|
AttributeLoc::Param(0),
|
||||||
|
type_attribute(env.context, "byval", zig_str_type(env).into()),
|
||||||
|
);
|
||||||
|
|
||||||
|
call.add_attribute(
|
||||||
|
AttributeLoc::Param(parameter_index as u32),
|
||||||
|
enum_attribute(env.context, "nonnull"),
|
||||||
|
);
|
||||||
|
|
||||||
|
call.add_attribute(
|
||||||
|
AttributeLoc::Param(parameter_index as u32),
|
||||||
|
enum_attribute(env.context, "nocapture"),
|
||||||
|
);
|
||||||
|
|
||||||
|
call.add_attribute(
|
||||||
|
AttributeLoc::Param(parameter_index as u32),
|
||||||
|
enum_attribute(env.context, "readonly"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn call_bitcode_fn_fixing_for_convention<'a, 'ctx, 'env>(
|
pub fn call_bitcode_fn_fixing_for_convention<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
args: &[BasicValueEnum<'ctx>],
|
args: &[BasicValueEnum<'ctx>],
|
||||||
|
|
|
@ -18,5 +18,5 @@ roc_collections = { path = "../collections" }
|
||||||
roc_load_internal = { path = "../load_internal" }
|
roc_load_internal = { path = "../load_internal" }
|
||||||
roc_builtins = { path = "../builtins" }
|
roc_builtins = { path = "../builtins" }
|
||||||
roc_module = { path = "../module" }
|
roc_module = { path = "../module" }
|
||||||
bumpalo = { version = "3.8.0", features = ["collections"] }
|
|
||||||
roc_target = { path = "../roc_target" }
|
roc_target = { path = "../roc_target" }
|
||||||
|
bumpalo = { version = "3.8.0", features = ["collections"] }
|
||||||
|
|
|
@ -554,6 +554,31 @@ impl<'a> UnionLayout<'a> {
|
||||||
|
|
||||||
(size, alignment_bytes)
|
(size, alignment_bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Very important to use this when doing a memcpy!
|
||||||
|
fn stack_size_without_alignment(&self, target_info: TargetInfo) -> u32 {
|
||||||
|
match self {
|
||||||
|
UnionLayout::NonRecursive(tags) => {
|
||||||
|
let id_layout = self.tag_id_layout();
|
||||||
|
|
||||||
|
let mut size = 0;
|
||||||
|
|
||||||
|
for field_layouts in tags.iter() {
|
||||||
|
let fields = Layout::struct_no_name_order(field_layouts);
|
||||||
|
let fields_and_id = [fields, id_layout];
|
||||||
|
|
||||||
|
let data = Layout::struct_no_name_order(&fields_and_id);
|
||||||
|
size = size.max(data.stack_size_without_alignment(target_info));
|
||||||
|
}
|
||||||
|
|
||||||
|
size
|
||||||
|
}
|
||||||
|
UnionLayout::Recursive(_)
|
||||||
|
| UnionLayout::NonNullableUnwrapped(_)
|
||||||
|
| UnionLayout::NullableWrapped { .. }
|
||||||
|
| UnionLayout::NullableUnwrapped { .. } => target_info.ptr_width() as u32,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Custom type so we can get the numeric representation of a symbol in tests (so `#UserApp.3`
|
/// Custom type so we can get the numeric representation of a symbol in tests (so `#UserApp.3`
|
||||||
|
@ -1042,7 +1067,8 @@ impl<'a> Layout<'a> {
|
||||||
(size, alignment)
|
(size, alignment)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stack_size_without_alignment(&self, target_info: TargetInfo) -> u32 {
|
/// Very important to use this when doing a memcpy!
|
||||||
|
pub fn stack_size_without_alignment(&self, target_info: TargetInfo) -> u32 {
|
||||||
use Layout::*;
|
use Layout::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
|
@ -1056,18 +1082,7 @@ impl<'a> Layout<'a> {
|
||||||
|
|
||||||
sum
|
sum
|
||||||
}
|
}
|
||||||
Union(variant) => {
|
Union(variant) => variant.stack_size_without_alignment(target_info),
|
||||||
use UnionLayout::*;
|
|
||||||
|
|
||||||
match variant {
|
|
||||||
NonRecursive(_) => variant.data_size_and_alignment(target_info).0,
|
|
||||||
|
|
||||||
Recursive(_)
|
|
||||||
| NullableWrapped { .. }
|
|
||||||
| NullableUnwrapped { .. }
|
|
||||||
| NonNullableUnwrapped(_) => target_info.ptr_width() as u32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LambdaSet(lambda_set) => lambda_set
|
LambdaSet(lambda_set) => lambda_set
|
||||||
.runtime_representation()
|
.runtime_representation()
|
||||||
.stack_size_without_alignment(target_info),
|
.stack_size_without_alignment(target_info),
|
||||||
|
@ -2950,4 +2965,16 @@ mod test {
|
||||||
assert_eq!(layout.stack_size(target_info), 1);
|
assert_eq!(layout.stack_size(target_info), 1);
|
||||||
assert_eq!(layout.alignment_bytes(target_info), 1);
|
assert_eq!(layout.alignment_bytes(target_info), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn memcpy_size_result_u32_unit() {
|
||||||
|
let ok_tag = &[Layout::Builtin(Builtin::Int(IntWidth::U32))];
|
||||||
|
let err_tag = &[Layout::UNIT];
|
||||||
|
let tags = [ok_tag as &[_], err_tag as &[_]];
|
||||||
|
let union_layout = UnionLayout::NonRecursive(&tags as &[_]);
|
||||||
|
let layout = Layout::Union(union_layout);
|
||||||
|
|
||||||
|
let target_info = TargetInfo::default_x86_64();
|
||||||
|
assert_eq!(layout.stack_size_without_alignment(target_info), 5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,7 +265,8 @@ pub fn helper<'a>(
|
||||||
let target = target_lexicon::Triple::host();
|
let target = target_lexicon::Triple::host();
|
||||||
|
|
||||||
let opt_level = if cfg!(debug_assertions) {
|
let opt_level = if cfg!(debug_assertions) {
|
||||||
OptLevel::Normal
|
// OptLevel::Normal
|
||||||
|
OptLevel::Optimize
|
||||||
} else {
|
} else {
|
||||||
OptLevel::Optimize
|
OptLevel::Optimize
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue