mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-11 18:58:24 +03:00
refactor glue roc calling logic
This commit is contained in:
parent
919a51137a
commit
2786e8ff7f
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user