diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index 98bd6bb3e3b..6856f2a0ec0 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, @@ -4437,31 +4437,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, @@ -4485,6 +4522,7 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>( output_arg, call_result, ); + builder.new_build_return(None); c_function 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 } diff --git a/crates/glue/src/load.rs b/crates/glue/src/load.rs index ab51d192778..b329d1fefc7 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}; @@ -123,14 +124,16 @@ 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) ); } 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}");