Regarding point 4: Meanwhile, I have found out that the #[start] attribute is not exclusive to no_std environments and can therefore also be used with libstd. Here is a working example:
#![feature(start)]
#![feature(termination_trait_lib)]
use std::{
process::Termination,
panic,
};
#[start]
fn start(_argc : isize, _argv : *const *const u8) -> isize {
panic::catch_unwind(|| sulong_main()).unwrap_or(101) as isize
}
fn sulong_main() -> i32{
main().report()
}
fn main() -> Result<(), &'static str> {
// panic!("panic");
Err("some error")
}
Unfortunately, #[start] and Termination are unstable. Moreover, it seems the idea behind #[start] is primarily to make it possible to define a C-style entry point. For my use case, it would be desirable to have a version of #[start] which can handle a lang_start-like signature, where the main function is passed as argument:
#[other_start]
fn start<T: Termination + 'static>
(main: fn() -> T, argc: isize, argv: *const *const u8) -> isize
{...}
A possible future Sulong crate could then just define such an entry point for programs written for the execution on Sulong. It would be tricky to achieve something that ergonomic using #[start]. I think it would require some boilerplate wrapped up in a macro on the user-side of the Sulong crate to make the main function callable from the start function defined in the Sulong crate.
I am wondering if I could safely emulate the functionality of the hypothetical #[other_start] attribute using Sulong’s symbol resolver. I could define an intrinsic for lang_start_internal in the hypothetical Sulong crate…
#[no_mangle]
fn __sulong_lang_start_internal(main: &(Fn() -> i32 + Sync + panic::RefUnwindSafe), argc: isize, argv: *const *const u8) -> isize {
panic::catch_unwind(|| main()).unwrap_or(101) as isize
}
… and then let Sulong replace the native call to the original lang_start_internal with a call to the lang_start_internal intrinsic. The Sulong crate would need to be compiled to bitcode too for this to work. This approach would be close to the currently implemented workaround. The difference is that the current lang_start_internal intrinsic is implemented in Java (which is kind of hacky) and that it doesn’t contain the call to catch_unwind.