mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 12:18:19 +00:00
be more precise with zig return types
This commit is contained in:
parent
ec80161824
commit
bb4ff34aaa
3 changed files with 68 additions and 14 deletions
|
@ -9,7 +9,7 @@ use crate::llvm::refcounting::{
|
|||
decrement_refcount_layout, increment_n_refcount_layout, increment_refcount_layout,
|
||||
};
|
||||
use inkwell::attributes::{Attribute, AttributeLoc};
|
||||
use inkwell::types::{BasicType, BasicTypeEnum};
|
||||
use inkwell::types::{BasicType, BasicTypeEnum, StructType};
|
||||
use inkwell::values::{
|
||||
BasicValue, BasicValueEnum, CallSiteValue, FunctionValue, InstructionValue, IntValue,
|
||||
PointerValue, StructValue,
|
||||
|
@ -97,6 +97,7 @@ fn call_bitcode_fn_help<'a, 'ctx, 'env>(
|
|||
|
||||
pub fn call_bitcode_fn_fixing_for_convention<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
bitcode_return_type: StructType<'ctx>,
|
||||
args: &[BasicValueEnum<'ctx>],
|
||||
return_layout: &Layout<'_>,
|
||||
fn_name: &str,
|
||||
|
@ -119,10 +120,7 @@ pub fn call_bitcode_fn_fixing_for_convention<'a, 'ctx, 'env>(
|
|||
.get_type()
|
||||
.get_param_types()[0]
|
||||
.into_pointer_type();
|
||||
let cc_return_type: BasicTypeEnum<'ctx> = cc_ptr_return_type
|
||||
.get_element_type()
|
||||
.try_into()
|
||||
.expect("Zig bitcode return type is not a basic type!");
|
||||
let cc_return_type: BasicTypeEnum<'ctx> = bitcode_return_type.into();
|
||||
|
||||
// when we write an i128 into this (happens in NumToInt), zig expects this pointer to
|
||||
// be 16-byte aligned. Not doing so is UB and will immediately fail on CI
|
||||
|
|
|
@ -447,6 +447,30 @@ pub fn zig_has_tag_id_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructT
|
|||
.struct_type(&[env.context.bool_type().into(), u8_ptr_t.into()], false)
|
||||
}
|
||||
|
||||
pub fn zig_num_parse_result_type<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
type_name: &str,
|
||||
) -> StructType<'ctx> {
|
||||
let name = format!("num.NumParseResult({type_name})");
|
||||
|
||||
match env.module.get_struct_type(&name) {
|
||||
Some(zig_type) => zig_type,
|
||||
None => panic!("zig does not define the `{name}` type!"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn zig_to_int_checked_result_type<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
type_name: &str,
|
||||
) -> StructType<'ctx> {
|
||||
let name = format!("num.ToIntCheckedResult({type_name})");
|
||||
|
||||
match env.module.get_struct_type(&name) {
|
||||
Some(zig_type) => zig_type,
|
||||
None => panic!("zig does not define the `{name}` type!"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn zig_with_overflow_roc_dec<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> {
|
||||
env.module
|
||||
.get_struct_type("utils.WithOverflow(dec.RocDec)")
|
||||
|
|
|
@ -33,7 +33,9 @@ use crate::llvm::{
|
|||
pass_update_mode,
|
||||
},
|
||||
compare::{generic_eq, generic_neq},
|
||||
convert::{self, basic_type_from_layout},
|
||||
convert::{
|
||||
self, basic_type_from_layout, zig_num_parse_result_type, zig_to_int_checked_result_type,
|
||||
},
|
||||
intrinsics::{
|
||||
LLVM_ADD_SATURATED, LLVM_ADD_WITH_OVERFLOW, LLVM_CEILING, LLVM_COS, LLVM_FABS, LLVM_FLOOR,
|
||||
LLVM_LOG, LLVM_MUL_WITH_OVERFLOW, LLVM_POW, LLVM_ROUND, LLVM_SIN, LLVM_SQRT,
|
||||
|
@ -257,7 +259,31 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
|
|||
}
|
||||
}
|
||||
PtrWidth::Bytes8 => {
|
||||
call_bitcode_fn_fixing_for_convention(env, &[string], layout, intrinsic)
|
||||
let cc_return_by_pointer = match number_layout {
|
||||
Layout::Builtin(Builtin::Int(int_width)) => {
|
||||
(int_width.stack_size() as usize > env.target_info.ptr_size())
|
||||
.then_some(int_width.type_name())
|
||||
}
|
||||
Layout::Builtin(Builtin::Decimal) => {
|
||||
// zig picks 128 for dec.RocDec
|
||||
Some("i128")
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(type_name) = cc_return_by_pointer {
|
||||
let bitcode_return_type = zig_num_parse_result_type(env, type_name);
|
||||
|
||||
call_bitcode_fn_fixing_for_convention(
|
||||
env,
|
||||
bitcode_return_type,
|
||||
&[string],
|
||||
layout,
|
||||
intrinsic,
|
||||
)
|
||||
} else {
|
||||
call_bitcode_fn(env, &[string], intrinsic)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1973,14 +1999,20 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
|||
}
|
||||
}
|
||||
PtrWidth::Bytes8 => {
|
||||
// call_bitcode_fn_fixing_for_convention(env, &[string], layout, intrinsic)
|
||||
if target_int_width.stack_size() as usize > env.target_info.ptr_size() {
|
||||
let bitcode_return_type =
|
||||
zig_to_int_checked_result_type(env, target_int_width.type_name());
|
||||
|
||||
call_bitcode_fn_fixing_for_convention(
|
||||
env,
|
||||
&[arg.into()],
|
||||
return_layout,
|
||||
intrinsic,
|
||||
)
|
||||
call_bitcode_fn_fixing_for_convention(
|
||||
env,
|
||||
bitcode_return_type,
|
||||
&[arg.into()],
|
||||
return_layout,
|
||||
intrinsic,
|
||||
)
|
||||
} else {
|
||||
call_bitcode_fn(env, &[arg.into()], intrinsic)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue