refactor glue roc calling logic

This commit is contained in:
Folkert 2024-01-27 18:14:12 +01:00
parent 919a51137a
commit 2786e8ff7f
No known key found for this signature in database
GPG Key ID: 1F17F6FFD112B97C

View File

@ -130,40 +130,13 @@ pub fn generate(
}
let lib = unsafe { Library::new(lib_path) }.unwrap();
type MakeGlueReturnType =
roc_std::RocResult<roc_std::RocList<roc_type::File>, roc_std::RocStr>;
type MakeGlue = unsafe extern "C" fn(
*mut RocCallResult<MakeGlueReturnType>,
&roc_std::RocList<roc_type::Types>,
);
let make_glue: libloading::Symbol<MakeGlue> = unsafe {
lib.get("roc__makeGlueForHost_1_exposed_generic".as_bytes())
.unwrap_or_else(|_| panic!("Unable to load glue function"))
};
let roc_types: roc_std::RocList<roc_type::Types> =
types.iter().map(|x| x.into()).collect();
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);
// NOTE: DO NOT DROP LIB! the return value will include static roc strings that
// are only kept alive when the dynamic library is not unloaded!
let files = call_roc_make_glue(&lib, backend, roc_types);
let files: Result<roc_std::RocList<roc_type::File>, roc_std::RocStr> =
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}");
process::exit(1);
});
for roc_type::File { name, content } in &files {
let valid_name = PathBuf::from(name.as_str())
.components()
@ -242,6 +215,44 @@ pub fn generate(
}
}
fn call_roc_make_glue(
lib: &Library,
backend: CodeGenBackend,
roc_types: roc_std::RocList<roc_type::Types>,
) -> roc_std::RocList<roc_type::File> {
type MakeGlueReturnType = roc_std::RocResult<roc_std::RocList<roc_type::File>, roc_std::RocStr>;
type MakeGlue = unsafe extern "C" fn(
*mut RocCallResult<MakeGlueReturnType>,
&roc_std::RocList<roc_type::Types>,
);
let name_of_main = "roc__makeGlueForHost_1_exposed_generic";
let make_glue: libloading::Symbol<MakeGlue> = unsafe {
lib.get(name_of_main.as_bytes())
.unwrap_or_else(|_| panic!("Unable to load glue function"))
};
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);
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(files_or_error) => match Result::from(files_or_error) {
Err(err) => {
eprintln!("Glue generation failed: {err}");
process::exit(1);
}
Ok(files) => files,
},
}
}
fn number_lambda_sets(subs: &Subs, initial: Variable) -> Vec<Variable> {
let mut lambda_sets = vec![];
let mut stack = vec![initial];