From 590282b14fc439c7a904eda6997e0468262bf812 Mon Sep 17 00:00:00 2001 From: Folkert Date: Mon, 11 Dec 2023 20:33:21 +0100 Subject: [PATCH 1/5] make glue use a setjmp/longjmp panic handler --- crates/compiler/gen_llvm/src/llvm/build.rs | 81 ++++++++++++++++------ crates/glue/src/load.rs | 19 +++-- 2 files changed, 75 insertions(+), 25 deletions(-) diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index 671b7fd6d5f..34048298383 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -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, @@ -4463,31 +4463,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 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() + ); - 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.set_current_debug_location(dbg_loc); - 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, + ) + } else { + debug_assert_eq!(args.len() + 1, roc_function.get_params().len()); - 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, - ) + 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, @@ -4511,6 +4548,8 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>( output_arg, call_result, ); + env.builder.new_build_store(output_arg, call_result); + builder.new_build_return(None); c_function diff --git a/crates/glue/src/load.rs b/crates/glue/src/load.rs index ab51d192778..6dffa7af6a1 100644 --- a/crates/glue/src/load.rs +++ b/crates/glue/src/load.rs @@ -11,8 +11,9 @@ use roc_build::{ }; use roc_collections::MutMap; use roc_error_macros::todo_lambda_erasure; +use roc_gen_llvm::run_roc::RocCallResult; use roc_load::{ExecutionMode, FunctionKind, LoadConfig, LoadedModule, LoadingProblem, Threading}; -use roc_mono::ir::{generate_glue_procs, GlueProc, OptLevel}; +use roc_mono::ir::{generate_glue_procs, CrashTag, GlueProc, OptLevel}; use roc_mono::layout::{GlobalLayoutInterner, LayoutCache, LayoutInterner}; use roc_packaging::cache::{self, RocCacheDir}; use roc_reporting::report::{RenderTarget, DEFAULT_PALETTE}; @@ -129,8 +130,10 @@ pub fn generate( } let lib = unsafe { Library::new(lib_path) }.unwrap(); + type MakeGlueReturnType = + roc_std::RocResult, roc_std::RocStr>; type MakeGlue = unsafe extern "C" fn( - *mut roc_std::RocResult, roc_std::RocStr>, + *mut RocCallResult, &roc_std::RocList, ); @@ -140,14 +143,22 @@ pub fn generate( }; let roc_types: roc_std::RocList = types.iter().map(|x| x.into()).collect(); - let mut files = roc_std::RocResult::err(roc_std::RocStr::empty()); + let mut files = + RocCallResult::new(roc_std::RocResult::err(roc_std::RocStr::empty())); unsafe { make_glue(&mut files, &roc_types) }; // Roc will free data passed into it. So forget that data. std::mem::forget(roc_types); let files: Result, roc_std::RocStr> = - files.into(); + match Result::from(files) { + Err((msg, tag)) => match tag { + CrashTag::Roc => panic!(r#"Roc failed with message: "{msg}""#), + CrashTag::User => panic!(r#"User crash with message: "{msg}""#), + }, + Ok(x) => x.into(), + }; + let files = files.unwrap_or_else(|err| { eprintln!("Glue generation failed: {err}"); From e1697a910cb760f4002b49e33ac18d36faf2d877 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Mon, 11 Dec 2023 14:35:49 -0500 Subject: [PATCH 2/5] cargo fmt --- crates/glue/src/glue.rs | 56 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/crates/glue/src/glue.rs b/crates/glue/src/glue.rs index 325ea22370d..e28bdf38b81 100644 --- a/crates/glue/src/glue.rs +++ b/crates/glue/src/glue.rs @@ -998,7 +998,7 @@ impl RocType { core::mem::ManuallyDrop::into_inner(swapped) }; - + payload } @@ -1016,7 +1016,7 @@ impl RocType { debug_assert_eq!(self.discriminant(), discriminant_RocType::Function); let payload = &self.Function; - + payload } @@ -1196,7 +1196,7 @@ impl RocType { let payload = self.RocDict; ( - payload.f0, + payload.f0, payload.f1 ) } @@ -1214,7 +1214,7 @@ impl RocType { let payload = &self.RocDict; ( - &payload.f0, + &payload.f0, &payload.f1 ) } @@ -1297,7 +1297,7 @@ impl RocType { let payload = self.RocResult; ( - payload.f0, + payload.f0, payload.f1 ) } @@ -1315,7 +1315,7 @@ impl RocType { let payload = &self.RocResult; ( - &payload.f0, + &payload.f0, &payload.f1 ) } @@ -1450,7 +1450,7 @@ impl RocType { core::mem::ManuallyDrop::into_inner(swapped) }; - + payload } @@ -1468,7 +1468,7 @@ impl RocType { debug_assert_eq!(self.discriminant(), discriminant_RocType::Struct); let payload = &self.Struct; - + payload } @@ -1580,7 +1580,7 @@ impl RocType { core::mem::ManuallyDrop::into_inner(swapped) }; - + payload } @@ -1598,7 +1598,7 @@ impl RocType { debug_assert_eq!(self.discriminant(), discriminant_RocType::TagUnionPayload); let payload = &self.TagUnionPayload; - + payload } @@ -1810,7 +1810,7 @@ impl RocType { let payload = self.RocDict; ( - payload.f0, + payload.f0, payload.f1 ) } @@ -1827,7 +1827,7 @@ impl RocType { let payload = &self.RocDict; ( - &payload.f0, + &payload.f0, &payload.f1 ) } @@ -1905,7 +1905,7 @@ impl RocType { let payload = self.RocResult; ( - payload.f0, + payload.f0, payload.f1 ) } @@ -1922,7 +1922,7 @@ impl RocType { let payload = &self.RocResult; ( - &payload.f0, + &payload.f0, &payload.f1 ) } @@ -2398,7 +2398,7 @@ impl RocTagUnion { core::mem::ManuallyDrop::into_inner(swapped) }; - + payload } @@ -2416,7 +2416,7 @@ impl RocTagUnion { debug_assert_eq!(self.discriminant(), discriminant_RocTagUnion::Enumeration); let payload = &self.Enumeration; - + payload } @@ -2464,7 +2464,7 @@ impl RocTagUnion { core::mem::ManuallyDrop::into_inner(swapped) }; - + payload } @@ -2482,7 +2482,7 @@ impl RocTagUnion { debug_assert_eq!(self.discriminant(), discriminant_RocTagUnion::NonNullableUnwrapped); let payload = &self.NonNullableUnwrapped; - + payload } @@ -2530,7 +2530,7 @@ impl RocTagUnion { core::mem::ManuallyDrop::into_inner(swapped) }; - + payload } @@ -2548,7 +2548,7 @@ impl RocTagUnion { debug_assert_eq!(self.discriminant(), discriminant_RocTagUnion::NonRecursive); let payload = &self.NonRecursive; - + payload } @@ -2596,7 +2596,7 @@ impl RocTagUnion { core::mem::ManuallyDrop::into_inner(swapped) }; - + payload } @@ -2614,7 +2614,7 @@ impl RocTagUnion { debug_assert_eq!(self.discriminant(), discriminant_RocTagUnion::NullableUnwrapped); let payload = &self.NullableUnwrapped; - + payload } @@ -2662,7 +2662,7 @@ impl RocTagUnion { core::mem::ManuallyDrop::into_inner(swapped) }; - + payload } @@ -2680,7 +2680,7 @@ impl RocTagUnion { debug_assert_eq!(self.discriminant(), discriminant_RocTagUnion::NullableWrapped); let payload = &self.NullableWrapped; - + payload } @@ -2728,7 +2728,7 @@ impl RocTagUnion { core::mem::ManuallyDrop::into_inner(swapped) }; - + payload } @@ -2746,7 +2746,7 @@ impl RocTagUnion { debug_assert_eq!(self.discriminant(), discriminant_RocTagUnion::Recursive); let payload = &self.Recursive; - + payload } @@ -2794,7 +2794,7 @@ impl RocTagUnion { core::mem::ManuallyDrop::into_inner(swapped) }; - + payload } @@ -2812,7 +2812,7 @@ impl RocTagUnion { debug_assert_eq!(self.discriminant(), discriminant_RocTagUnion::SingleTagStruct); let payload = &self.SingleTagStruct; - + payload } From 5aab05aede026321f8ef8db65b1d382c13245cbf Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Mon, 11 Dec 2023 14:36:37 -0500 Subject: [PATCH 3/5] Change `Running program...` message in glue --- crates/glue/src/load.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/glue/src/load.rs b/crates/glue/src/load.rs index 6dffa7af6a1..b329d1fefc7 100644 --- a/crates/glue/src/load.rs +++ b/crates/glue/src/load.rs @@ -124,7 +124,7 @@ pub fn generate( if problems.warnings > 0 { problems.print_to_stdout(total_time); println!( - ".\n\nRunning program…\n\n\x1B[36m{}\x1B[39m", + ".\n\nRunning glue despite warnings…\n\n\x1B[36m{}\x1B[39m", "─".repeat(80) ); } From d2d87949c882c3732b686f38fd9a984dce996320 Mon Sep 17 00:00:00 2001 From: Folkert Date: Mon, 11 Dec 2023 21:07:04 +0100 Subject: [PATCH 4/5] remove random write to pointer --- crates/compiler/gen_llvm/src/llvm/build.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index 34048298383..954ed5d5eb7 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -4464,6 +4464,7 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>( } let call_result = if env.mode.returns_roc_result() { + assert!(false); if args.len() == roc_function.get_params().len() { let arguments_for_call = &arguments_for_call.into_bump_slice(); @@ -4487,6 +4488,7 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>( arguments_for_call, ) } else { + assert!(false); debug_assert_eq!(args.len() + 1, roc_function.get_params().len()); arguments_for_call.push(args[0]); @@ -4548,7 +4550,6 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>( output_arg, call_result, ); - env.builder.new_build_store(output_arg, call_result); builder.new_build_return(None); From 67d7385b9ade10fded9b4f5adcb11e49a5ad6827 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Mon, 11 Dec 2023 15:15:59 -0500 Subject: [PATCH 5/5] Clean up some obsolete asserts --- crates/compiler/gen_llvm/src/llvm/build.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index 954ed5d5eb7..104c0d0f5a4 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -4464,7 +4464,6 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>( } let call_result = if env.mode.returns_roc_result() { - assert!(false); if args.len() == roc_function.get_params().len() { let arguments_for_call = &arguments_for_call.into_bump_slice(); @@ -4488,7 +4487,6 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>( arguments_for_call, ) } else { - assert!(false); debug_assert_eq!(args.len() + 1, roc_function.get_params().len()); arguments_for_call.push(args[0]);