mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-24 06:55:15 +00:00
Merge branch 'main' of github.com:roc-lang/roc into clippy-1.74
This commit is contained in:
commit
cd632fe549
271 changed files with 7741 additions and 7417 deletions
|
@ -30,12 +30,25 @@ pub fn call_bitcode_fn<'ctx>(
|
|||
args: &[BasicValueEnum<'ctx>],
|
||||
fn_name: &str,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
call_bitcode_fn_help(env, args, fn_name)
|
||||
let ret = call_bitcode_fn_help(env, args, fn_name)
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("LLVM error: Did not get return value from bitcode function {fn_name:?}")
|
||||
})
|
||||
});
|
||||
|
||||
if env.target_info.operating_system == roc_target::OperatingSystem::Windows {
|
||||
// On windows zig uses a vector type <2xi64> instead of a i128 value
|
||||
let vec_type = env.context.i64_type().vec_type(2);
|
||||
if ret.get_type() == vec_type.into() {
|
||||
return env
|
||||
.builder
|
||||
.build_bitcast(ret, env.context.i128_type(), "return_i128")
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn call_void_bitcode_fn<'ctx>(
|
||||
|
@ -54,7 +67,35 @@ fn call_bitcode_fn_help<'ctx>(
|
|||
args: &[BasicValueEnum<'ctx>],
|
||||
fn_name: &str,
|
||||
) -> CallSiteValue<'ctx> {
|
||||
let it = args.iter().map(|x| (*x).into());
|
||||
let it = args
|
||||
.iter()
|
||||
.map(|x| {
|
||||
if env.target_info.operating_system == roc_target::OperatingSystem::Windows {
|
||||
if x.get_type() == env.context.i128_type().into() {
|
||||
let parent = env
|
||||
.builder
|
||||
.get_insert_block()
|
||||
.and_then(|b| b.get_parent())
|
||||
.unwrap();
|
||||
|
||||
let alloca = create_entry_block_alloca(
|
||||
env,
|
||||
parent,
|
||||
x.get_type(),
|
||||
"pass_u128_by_reference",
|
||||
);
|
||||
|
||||
env.builder.build_store(alloca, *x).unwrap();
|
||||
|
||||
alloca.into()
|
||||
} else {
|
||||
*x
|
||||
}
|
||||
} else {
|
||||
*x
|
||||
}
|
||||
})
|
||||
.map(|x| (x).into());
|
||||
let arguments = bumpalo::collections::Vec::from_iter_in(it, env.arena);
|
||||
|
||||
let fn_val = env
|
||||
|
|
|
@ -710,7 +710,7 @@ impl LlvmBackendMode {
|
|||
match self {
|
||||
LlvmBackendMode::Binary => false,
|
||||
LlvmBackendMode::BinaryDev => false,
|
||||
LlvmBackendMode::BinaryGlue => false,
|
||||
LlvmBackendMode::BinaryGlue => true,
|
||||
LlvmBackendMode::GenTest => true,
|
||||
LlvmBackendMode::WasmGenTest => true,
|
||||
LlvmBackendMode::CliTest => true,
|
||||
|
@ -910,16 +910,19 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
|
|||
&self,
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
location: BasicValueEnum<'ctx>,
|
||||
source: BasicValueEnum<'ctx>,
|
||||
message: BasicValueEnum<'ctx>,
|
||||
) {
|
||||
let function = self.module.get_function("roc_dbg").unwrap();
|
||||
|
||||
let loc = self.string_to_arg(env, location);
|
||||
let src = self.string_to_arg(env, source);
|
||||
let msg = self.string_to_arg(env, message);
|
||||
|
||||
let call = self
|
||||
.builder
|
||||
.new_build_call(function, &[loc.into(), msg.into()], "roc_dbg");
|
||||
// TODO: at some point it will be a breaking change, but flip order to (loc, src, msg)
|
||||
let call =
|
||||
self.builder
|
||||
.new_build_call(function, &[loc.into(), msg.into(), src.into()], "roc_dbg");
|
||||
|
||||
call.set_call_convention(C_CALL_CONV);
|
||||
}
|
||||
|
@ -1055,6 +1058,55 @@ pub fn module_from_builtins<'ctx>(
|
|||
let module = Module::parse_bitcode_from_buffer(&memory_buffer, ctx)
|
||||
.unwrap_or_else(|err| panic!("Unable to import builtins bitcode. LLVM error: {err:?}"));
|
||||
|
||||
// In testing, this adds about 20ms extra to compilation.
|
||||
// Long term it would be best if we could do this on the zig side.
|
||||
// The core issue is that we have to properly labael certain functions as private and DCE them.
|
||||
// Otherwise, now that zig bundles all of compiler-rt, we would optimize and compile the entire library.
|
||||
// Anything not depended on by a `roc_builtin.` function could already by DCE'd theoretically.
|
||||
// That said, this workaround is good enough and fixes compilations times.
|
||||
|
||||
// Also, must_keep is the functions we depend on that would normally be provide by libc.
|
||||
// They are magically linked to by llvm builtins, so we must specify that they can't be DCE'd.
|
||||
let must_keep = [
|
||||
"_fltused",
|
||||
"floorf",
|
||||
"memcpy",
|
||||
"memset",
|
||||
// I have no idea why this function is special.
|
||||
// Without it, some tests hang on M1 mac outside of nix.
|
||||
"__muloti4",
|
||||
// fixes `Undefined Symbol in relocation`
|
||||
"__udivti3",
|
||||
// Roc special functions
|
||||
"__roc_force_longjmp",
|
||||
"__roc_force_setjmp",
|
||||
"set_shared_buffer",
|
||||
];
|
||||
for func in module.get_functions() {
|
||||
let has_definition = func.count_basic_blocks() > 0;
|
||||
let name = func.get_name().to_string_lossy();
|
||||
if has_definition
|
||||
&& !name.starts_with("roc_builtins.")
|
||||
&& !must_keep.contains(&name.as_ref())
|
||||
{
|
||||
func.set_linkage(Linkage::Private);
|
||||
}
|
||||
}
|
||||
|
||||
// Note, running DCE here is faster then waiting until full app DCE.
|
||||
let mpm = PassManager::create(());
|
||||
mpm.add_global_dce_pass();
|
||||
mpm.run_on(&module);
|
||||
|
||||
// Now that the unused compiler-rt functions have been removed,
|
||||
// mark that the builtin functions are allowed to be DCE'd if they aren't used.
|
||||
for func in module.get_functions() {
|
||||
let name = func.get_name().to_string_lossy();
|
||||
if name.starts_with("roc_builtins.") {
|
||||
func.set_linkage(Linkage::Private);
|
||||
}
|
||||
}
|
||||
|
||||
// Add LLVM intrinsics.
|
||||
add_intrinsics(ctx, &module);
|
||||
|
||||
|
@ -1227,6 +1279,8 @@ fn promote_to_wasm_test_wrapper<'a, 'ctx>(
|
|||
let subprogram = env.new_subprogram(main_fn_name);
|
||||
c_function.set_subprogram(subprogram);
|
||||
|
||||
debug_info_init!(env, c_function);
|
||||
|
||||
// STEP 2: build the exposed function's body
|
||||
let builder = env.builder;
|
||||
let context = env.context;
|
||||
|
@ -3527,17 +3581,17 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
|
|||
}
|
||||
|
||||
Dbg {
|
||||
source_location,
|
||||
source,
|
||||
symbol,
|
||||
variable: _,
|
||||
remainder,
|
||||
} => {
|
||||
if env.mode.runs_expects() {
|
||||
// TODO: Change location to `filename:line_number`
|
||||
// let region = unsafe { std::mem::transmute::<_, roc_region::all::Region>(*symbol) };
|
||||
let location =
|
||||
build_string_literal(env, parent, symbol.module_string(&env.interns));
|
||||
let location = build_string_literal(env, parent, source_location);
|
||||
let source = build_string_literal(env, parent, source);
|
||||
let message = scope.load_symbol(symbol);
|
||||
env.call_dbg(env, location, message);
|
||||
env.call_dbg(env, location, source, message);
|
||||
}
|
||||
|
||||
build_exp_stmt(
|
||||
|
@ -4363,6 +4417,8 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>(
|
|||
let subprogram = env.new_subprogram(c_function_name);
|
||||
c_function.set_subprogram(subprogram);
|
||||
|
||||
debug_info_init!(env, c_function);
|
||||
|
||||
// STEP 2: build the exposed function's body
|
||||
let builder = env.builder;
|
||||
let context = env.context;
|
||||
|
@ -4371,8 +4427,6 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>(
|
|||
|
||||
builder.position_at_end(entry);
|
||||
|
||||
debug_info_init!(env, c_function);
|
||||
|
||||
// drop the first argument, which is the pointer we write the result into
|
||||
let args_vector = c_function.get_params();
|
||||
let mut args = args_vector.as_slice();
|
||||
|
@ -4413,29 +4467,68 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>(
|
|||
}
|
||||
}
|
||||
|
||||
let arguments_for_call = &arguments_for_call.into_bump_slice();
|
||||
|
||||
let call_result = if env.mode.returns_roc_result() {
|
||||
debug_assert_eq!(args.len(), roc_function.get_params().len());
|
||||
if args.len() == roc_function.get_params().len() {
|
||||
let arguments_for_call = &arguments_for_call.into_bump_slice();
|
||||
|
||||
let roc_wrapper_function =
|
||||
make_exception_catcher(env, layout_interner, roc_function, return_layout);
|
||||
debug_assert_eq!(
|
||||
arguments_for_call.len(),
|
||||
roc_wrapper_function.get_params().len()
|
||||
);
|
||||
let dbg_loc = builder.get_current_debug_location().unwrap();
|
||||
let roc_wrapper_function =
|
||||
make_exception_catcher(env, layout_interner, roc_function, return_layout);
|
||||
debug_assert_eq!(
|
||||
arguments_for_call.len(),
|
||||
roc_wrapper_function.get_params().len()
|
||||
);
|
||||
|
||||
builder.position_at_end(entry);
|
||||
builder.position_at_end(entry);
|
||||
builder.set_current_debug_location(dbg_loc);
|
||||
|
||||
let wrapped_layout = roc_call_result_layout(env.arena, return_layout);
|
||||
call_direct_roc_function(
|
||||
env,
|
||||
layout_interner,
|
||||
roc_function,
|
||||
wrapped_layout,
|
||||
arguments_for_call,
|
||||
)
|
||||
let wrapped_layout = roc_call_result_layout(env.arena, return_layout);
|
||||
call_direct_roc_function(
|
||||
env,
|
||||
layout_interner,
|
||||
roc_function,
|
||||
wrapped_layout,
|
||||
arguments_for_call,
|
||||
)
|
||||
} else {
|
||||
debug_assert_eq!(args.len() + 1, roc_function.get_params().len());
|
||||
|
||||
arguments_for_call.push(args[0]);
|
||||
|
||||
let arguments_for_call = &arguments_for_call.into_bump_slice();
|
||||
|
||||
let dbg_loc = builder.get_current_debug_location().unwrap();
|
||||
let roc_wrapper_function =
|
||||
make_exception_catcher(env, layout_interner, roc_function, return_layout);
|
||||
|
||||
builder.position_at_end(entry);
|
||||
builder.set_current_debug_location(dbg_loc);
|
||||
|
||||
let wrapped_layout = roc_call_result_layout(env.arena, return_layout);
|
||||
let call_result = call_direct_roc_function(
|
||||
env,
|
||||
layout_interner,
|
||||
roc_wrapper_function,
|
||||
wrapped_layout,
|
||||
arguments_for_call,
|
||||
);
|
||||
|
||||
let output_arg_index = 0;
|
||||
|
||||
let output_arg = c_function
|
||||
.get_nth_param(output_arg_index as u32)
|
||||
.unwrap()
|
||||
.into_pointer_value();
|
||||
|
||||
env.builder.new_build_store(output_arg, call_result);
|
||||
|
||||
builder.new_build_return(None);
|
||||
|
||||
return c_function;
|
||||
}
|
||||
} else {
|
||||
let arguments_for_call = &arguments_for_call.into_bump_slice();
|
||||
|
||||
call_direct_roc_function(
|
||||
env,
|
||||
layout_interner,
|
||||
|
@ -4459,6 +4552,7 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>(
|
|||
output_arg,
|
||||
call_result,
|
||||
);
|
||||
|
||||
builder.new_build_return(None);
|
||||
|
||||
c_function
|
||||
|
@ -4511,6 +4605,8 @@ fn expose_function_to_host_help_c_abi_gen_test<'a, 'ctx>(
|
|||
let subprogram = env.new_subprogram(c_function_name);
|
||||
c_function.set_subprogram(subprogram);
|
||||
|
||||
debug_info_init!(env, c_function);
|
||||
|
||||
// STEP 2: build the exposed function's body
|
||||
let builder = env.builder;
|
||||
let context = env.context;
|
||||
|
@ -4519,8 +4615,6 @@ fn expose_function_to_host_help_c_abi_gen_test<'a, 'ctx>(
|
|||
|
||||
builder.position_at_end(entry);
|
||||
|
||||
debug_info_init!(env, c_function);
|
||||
|
||||
// drop the final argument, which is the pointer we write the result into
|
||||
let args_vector = c_function.get_params();
|
||||
let mut args = args_vector.as_slice();
|
||||
|
@ -4567,10 +4661,12 @@ fn expose_function_to_host_help_c_abi_gen_test<'a, 'ctx>(
|
|||
let (call_result, call_result_layout) = {
|
||||
let last_block = builder.get_insert_block().unwrap();
|
||||
|
||||
let dbg_loc = builder.get_current_debug_location().unwrap();
|
||||
let roc_wrapper_function =
|
||||
make_exception_catcher(env, layout_interner, roc_function, return_layout);
|
||||
|
||||
builder.position_at_end(last_block);
|
||||
builder.set_current_debug_location(dbg_loc);
|
||||
|
||||
let wrapper_result = roc_call_result_layout(env.arena, return_layout);
|
||||
|
||||
|
@ -4622,12 +4718,12 @@ fn expose_function_to_host_help_c_abi_gen_test<'a, 'ctx>(
|
|||
let subprogram = env.new_subprogram(&size_function_name);
|
||||
size_function.set_subprogram(subprogram);
|
||||
|
||||
debug_info_init!(env, size_function);
|
||||
|
||||
let entry = context.append_basic_block(size_function, "entry");
|
||||
|
||||
builder.position_at_end(entry);
|
||||
|
||||
debug_info_init!(env, size_function);
|
||||
|
||||
let size: BasicValueEnum = return_type.size_of().unwrap().into();
|
||||
builder.new_build_return(Some(&size));
|
||||
|
||||
|
@ -4713,6 +4809,8 @@ fn expose_function_to_host_help_c_abi_v2<'a, 'ctx>(
|
|||
let subprogram = env.new_subprogram(c_function_name);
|
||||
c_function.set_subprogram(subprogram);
|
||||
|
||||
debug_info_init!(env, c_function);
|
||||
|
||||
// STEP 2: build the exposed function's body
|
||||
let builder = env.builder;
|
||||
let context = env.context;
|
||||
|
@ -4941,12 +5039,12 @@ fn expose_function_to_host_help_c_abi<'a, 'ctx>(
|
|||
let subprogram = env.new_subprogram(&size_function_name);
|
||||
size_function.set_subprogram(subprogram);
|
||||
|
||||
debug_info_init!(env, size_function);
|
||||
|
||||
let entry = env.context.append_basic_block(size_function, "entry");
|
||||
|
||||
env.builder.position_at_end(entry);
|
||||
|
||||
debug_info_init!(env, size_function);
|
||||
|
||||
let return_type = match env.mode {
|
||||
LlvmBackendMode::GenTest | LlvmBackendMode::WasmGenTest | LlvmBackendMode::CliTest => {
|
||||
roc_call_result_type(env, roc_function.get_type().get_return_type().unwrap()).into()
|
||||
|
@ -5343,6 +5441,8 @@ fn make_exception_catching_wrapper<'a, 'ctx>(
|
|||
let subprogram = env.new_subprogram(wrapper_function_name);
|
||||
wrapper_function.set_subprogram(subprogram);
|
||||
|
||||
debug_info_init!(env, wrapper_function);
|
||||
|
||||
// The exposed main function must adhere to the C calling convention, but the wrapper can still be fastcc.
|
||||
wrapper_function.set_call_conventions(FAST_CALL_CONV);
|
||||
|
||||
|
@ -5819,6 +5919,8 @@ fn build_proc_header<'a, 'ctx>(
|
|||
let subprogram = env.new_subprogram(&fn_name);
|
||||
fn_val.set_subprogram(subprogram);
|
||||
|
||||
debug_info_init!(env, fn_val);
|
||||
|
||||
if env.exposed_to_host.contains(&symbol) {
|
||||
let arguments = Vec::from_iter_in(proc.args.iter().map(|(layout, _)| *layout), env.arena);
|
||||
expose_function_to_host(
|
||||
|
|
|
@ -450,7 +450,7 @@ pub(crate) fn list_capacity_or_ref_ptr<'ctx>(
|
|||
|
||||
// Gets a pointer to just after the refcount for a list or seamless slice.
|
||||
// The value is just after the refcount so that normal lists and seamless slices can share code paths easily.
|
||||
pub(crate) fn list_refcount_ptr<'ctx>(
|
||||
pub(crate) fn list_allocation_ptr<'ctx>(
|
||||
env: &Env<'_, 'ctx, '_>,
|
||||
wrapper_struct: StructValue<'ctx>,
|
||||
) -> PointerValue<'ctx> {
|
||||
|
@ -459,7 +459,7 @@ pub(crate) fn list_refcount_ptr<'ctx>(
|
|||
&[wrapper_struct],
|
||||
&[],
|
||||
BitcodeReturns::Basic,
|
||||
bitcode::LIST_REFCOUNT_PTR,
|
||||
bitcode::LIST_ALLOCATION_PTR,
|
||||
)
|
||||
.into_pointer_value()
|
||||
}
|
||||
|
@ -864,7 +864,7 @@ pub(crate) fn decref<'ctx>(
|
|||
wrapper_struct: StructValue<'ctx>,
|
||||
alignment: u32,
|
||||
) {
|
||||
let refcount_ptr = list_refcount_ptr(env, wrapper_struct);
|
||||
let refcount_ptr = list_allocation_ptr(env, wrapper_struct);
|
||||
|
||||
crate::llvm::refcounting::decref_pointer_check_null(env, refcount_ptr, alignment);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ pub(crate) fn str_equal<'ctx>(
|
|||
|
||||
// Gets a pointer to just after the refcount for a list or seamless slice.
|
||||
// The value is just after the refcount so that normal lists and seamless slices can share code paths easily.
|
||||
pub(crate) fn str_refcount_ptr<'ctx>(
|
||||
pub(crate) fn str_allocation_ptr<'ctx>(
|
||||
env: &Env<'_, 'ctx, '_>,
|
||||
value: BasicValueEnum<'ctx>,
|
||||
) -> PointerValue<'ctx> {
|
||||
|
@ -57,7 +57,7 @@ pub(crate) fn str_refcount_ptr<'ctx>(
|
|||
&[value],
|
||||
&[],
|
||||
BitcodeReturns::Basic,
|
||||
bitcode::STR_REFCOUNT_PTR,
|
||||
bitcode::STR_ALLOCATION_PTR,
|
||||
)
|
||||
.into_pointer_value()
|
||||
}
|
||||
|
|
|
@ -469,6 +469,8 @@ fn build_clone_tag<'a, 'ctx>(
|
|||
let subprogram = env.new_subprogram(&fn_name);
|
||||
function_value.set_subprogram(subprogram);
|
||||
|
||||
debug_info_init!(env, function_value);
|
||||
|
||||
env.dibuilder.finalize();
|
||||
|
||||
build_clone_tag_help(
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::debug_info_init;
|
||||
use crate::llvm::bitcode::call_void_bitcode_fn;
|
||||
use crate::llvm::build::{add_func, get_panic_msg_ptr, get_panic_tag_ptr, BuilderExt, C_CALL_CONV};
|
||||
use crate::llvm::build::{CCReturn, Env, FunctionSpec};
|
||||
|
@ -160,8 +161,39 @@ pub fn add_default_roc_externs(env: &Env<'_, '_, '_>) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: generate a valid impl of dbg here.
|
||||
unreachable_function(env, "roc_dbg");
|
||||
// roc_dbg
|
||||
{
|
||||
// The type of this function (but not the implementation) should have
|
||||
// already been defined by the builtins, which rely on it.
|
||||
let fn_val = module.get_function("roc_dbg").unwrap();
|
||||
let mut params = fn_val.get_param_iter();
|
||||
let loc_arg = params.next().unwrap();
|
||||
let msg_arg = params.next().unwrap();
|
||||
let src_arg = params.next().unwrap();
|
||||
|
||||
debug_assert!(params.next().is_none());
|
||||
|
||||
// Add a basic block for the entry point
|
||||
let entry = ctx.append_basic_block(fn_val, "entry");
|
||||
|
||||
builder.position_at_end(entry);
|
||||
|
||||
// Call utils.dbg_impl()
|
||||
let dbg_impl = module.get_function(bitcode::UTILS_DBG_IMPL).unwrap();
|
||||
let call = builder.new_build_call(
|
||||
dbg_impl,
|
||||
&[loc_arg.into(), msg_arg.into(), src_arg.into()],
|
||||
"call_utils_dbg_impl",
|
||||
);
|
||||
|
||||
call.set_call_convention(C_CALL_CONV);
|
||||
|
||||
builder.new_build_return(None);
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
crate::llvm::build::verify_fn(fn_val);
|
||||
}
|
||||
}
|
||||
|
||||
match env.target_info.operating_system {
|
||||
roc_target::OperatingSystem::Windows => {
|
||||
|
@ -223,6 +255,8 @@ pub fn add_sjlj_roc_panic(env: &Env<'_, '_, '_>) {
|
|||
let subprogram = env.new_subprogram("roc_panic");
|
||||
fn_val.set_subprogram(subprogram);
|
||||
|
||||
debug_info_init!(env, fn_val);
|
||||
|
||||
env.dibuilder.finalize();
|
||||
|
||||
// Add a basic block for the entry point
|
||||
|
|
|
@ -80,10 +80,6 @@ pub(crate) fn add_intrinsics<'ctx>(ctx: &'ctx Context, module: &Module<'ctx>) {
|
|||
let i32_type = ctx.i32_type();
|
||||
let void_type = ctx.void_type();
|
||||
|
||||
if let Some(func) = module.get_function("__muloti4") {
|
||||
func.set_linkage(Linkage::WeakAny);
|
||||
}
|
||||
|
||||
add_intrinsic(
|
||||
ctx,
|
||||
module,
|
||||
|
|
|
@ -1100,13 +1100,22 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
NumBytesToU128 => {
|
||||
arguments!(list, position);
|
||||
|
||||
call_list_bitcode_fn(
|
||||
let ret = call_list_bitcode_fn(
|
||||
env,
|
||||
&[list.into_struct_value()],
|
||||
&[position],
|
||||
BitcodeReturns::Basic,
|
||||
bitcode::NUM_BYTES_TO_U128,
|
||||
)
|
||||
);
|
||||
|
||||
if env.target_info.operating_system == roc_target::OperatingSystem::Windows {
|
||||
// On windows the return type is not a i128, likely due to alignment
|
||||
env.builder
|
||||
.build_bitcast(ret, env.context.i128_type(), "empty_string")
|
||||
.unwrap()
|
||||
} else {
|
||||
ret
|
||||
}
|
||||
}
|
||||
NumCompare => {
|
||||
arguments_with_layouts!((lhs_arg, lhs_layout), (rhs_arg, rhs_layout));
|
||||
|
@ -1535,7 +1544,7 @@ fn build_int_binop<'ctx>(
|
|||
)
|
||||
.into_struct_value();
|
||||
|
||||
throw_on_overflow(env, parent, result, "integer addition overflowed!")
|
||||
throw_on_overflow(env, parent, result, "Integer addition overflowed!")
|
||||
}
|
||||
NumAddWrap => bd.new_build_int_add(lhs, rhs, "add_int_wrap").into(),
|
||||
NumAddChecked => {
|
||||
|
@ -1566,7 +1575,7 @@ fn build_int_binop<'ctx>(
|
|||
)
|
||||
.into_struct_value();
|
||||
|
||||
throw_on_overflow(env, parent, result, "integer subtraction overflowed!")
|
||||
throw_on_overflow(env, parent, result, "Integer subtraction overflowed!")
|
||||
}
|
||||
NumSubWrap => bd.new_build_int_sub(lhs, rhs, "sub_int").into(),
|
||||
NumSubChecked => {
|
||||
|
@ -1597,7 +1606,7 @@ fn build_int_binop<'ctx>(
|
|||
)
|
||||
.into_struct_value();
|
||||
|
||||
throw_on_overflow(env, parent, result, "integer multiplication overflowed!")
|
||||
throw_on_overflow(env, parent, result, "Integer multiplication overflowed!")
|
||||
}
|
||||
NumMulWrap => bd.new_build_int_mul(lhs, rhs, "mul_int").into(),
|
||||
NumMulSaturated => call_bitcode_fn(
|
||||
|
@ -2350,7 +2359,7 @@ fn build_dec_binop<'a, 'ctx>(
|
|||
bitcode::DEC_ADD_WITH_OVERFLOW,
|
||||
lhs,
|
||||
rhs,
|
||||
"decimal addition overflowed",
|
||||
"Decimal addition overflowed",
|
||||
),
|
||||
NumSub => build_dec_binop_throw_on_overflow(
|
||||
env,
|
||||
|
@ -2358,7 +2367,7 @@ fn build_dec_binop<'a, 'ctx>(
|
|||
bitcode::DEC_SUB_WITH_OVERFLOW,
|
||||
lhs,
|
||||
rhs,
|
||||
"decimal subtraction overflowed",
|
||||
"Decimal subtraction overflowed",
|
||||
),
|
||||
NumMul => build_dec_binop_throw_on_overflow(
|
||||
env,
|
||||
|
@ -2366,7 +2375,7 @@ fn build_dec_binop<'a, 'ctx>(
|
|||
bitcode::DEC_MUL_WITH_OVERFLOW,
|
||||
lhs,
|
||||
rhs,
|
||||
"decimal multiplication overflowed",
|
||||
"Decimal multiplication overflowed",
|
||||
),
|
||||
NumDivFrac => dec_binop_with_unchecked(env, bitcode::DEC_DIV, lhs, rhs),
|
||||
|
||||
|
@ -2596,7 +2605,16 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
|||
}
|
||||
}
|
||||
PtrWidth::Bytes8 => {
|
||||
if target_int_width.stack_size() as usize > env.target_info.ptr_size() {
|
||||
let return_by_pointer = {
|
||||
if env.target_info.operating_system
|
||||
== roc_target::OperatingSystem::Windows
|
||||
{
|
||||
target_int_width.stack_size() as usize >= env.target_info.ptr_size()
|
||||
} else {
|
||||
target_int_width.stack_size() as usize > env.target_info.ptr_size()
|
||||
}
|
||||
};
|
||||
if return_by_pointer {
|
||||
let bitcode_return_type =
|
||||
zig_to_int_checked_result_type(env, target_int_width.type_name());
|
||||
|
||||
|
@ -2659,7 +2677,7 @@ fn int_neg_raise_on_overflow<'ctx>(
|
|||
throw_internal_exception(
|
||||
env,
|
||||
parent,
|
||||
"integer negation overflowed because its argument is the minimum value",
|
||||
"Integer negation overflowed because its argument is the minimum value",
|
||||
);
|
||||
|
||||
builder.position_at_end(else_block);
|
||||
|
@ -2690,7 +2708,7 @@ fn int_abs_raise_on_overflow<'ctx>(
|
|||
throw_internal_exception(
|
||||
env,
|
||||
parent,
|
||||
"integer absolute overflowed because its argument is the minimum value",
|
||||
"Integer absolute overflowed because its argument is the minimum value",
|
||||
);
|
||||
|
||||
builder.position_at_end(else_block);
|
||||
|
|
|
@ -5,9 +5,9 @@ use crate::llvm::build::{
|
|||
add_func, cast_basic_basic, get_tag_id, tag_pointer_clear_tag_id, Env, FAST_CALL_CONV,
|
||||
};
|
||||
use crate::llvm::build_list::{
|
||||
incrementing_elem_loop, list_capacity_or_ref_ptr, list_refcount_ptr, load_list,
|
||||
incrementing_elem_loop, list_allocation_ptr, list_capacity_or_ref_ptr, load_list,
|
||||
};
|
||||
use crate::llvm::build_str::str_refcount_ptr;
|
||||
use crate::llvm::build_str::str_allocation_ptr;
|
||||
use crate::llvm::convert::{basic_type_from_layout, zig_str_type, RocUnion};
|
||||
use crate::llvm::struct_::RocStruct;
|
||||
use bumpalo::collections::Vec;
|
||||
|
@ -156,6 +156,8 @@ impl<'ctx> PointerToRefcount<'ctx> {
|
|||
let subprogram = env.new_subprogram(fn_name);
|
||||
function_value.set_subprogram(subprogram);
|
||||
|
||||
debug_info_init!(env, function_value);
|
||||
|
||||
Self::build_decrement_function_body(env, function_value, alignment);
|
||||
|
||||
function_value
|
||||
|
@ -864,7 +866,7 @@ fn modify_refcount_list_help<'a, 'ctx>(
|
|||
}
|
||||
|
||||
let refcount_ptr =
|
||||
PointerToRefcount::from_ptr_to_data(env, list_refcount_ptr(env, original_wrapper));
|
||||
PointerToRefcount::from_ptr_to_data(env, list_allocation_ptr(env, original_wrapper));
|
||||
let call_mode = mode_to_call_mode(fn_val, mode);
|
||||
refcount_ptr.modify(call_mode, layout, env, layout_interner);
|
||||
|
||||
|
@ -971,7 +973,7 @@ fn modify_refcount_str_help<'a, 'ctx>(
|
|||
builder.new_build_conditional_branch(is_big_and_non_empty, modification_block, cont_block);
|
||||
builder.position_at_end(modification_block);
|
||||
|
||||
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, str_refcount_ptr(env, arg_val));
|
||||
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, str_allocation_ptr(env, arg_val));
|
||||
let call_mode = mode_to_call_mode(fn_val, mode);
|
||||
refcount_ptr.modify(
|
||||
call_mode,
|
||||
|
@ -1049,6 +1051,8 @@ pub fn build_header_help<'ctx>(
|
|||
let subprogram = env.new_subprogram(fn_name);
|
||||
fn_val.set_subprogram(subprogram);
|
||||
|
||||
debug_info_init!(env, fn_val);
|
||||
|
||||
env.dibuilder.finalize();
|
||||
|
||||
fn_val
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue