mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Normalize c/Roc callconv parameters when C returns by pointer
Closes #2413
This commit is contained in:
parent
365b3bb9c0
commit
1a1eaf7f68
2 changed files with 46 additions and 5 deletions
|
@ -3600,11 +3600,14 @@ fn expose_function_to_host_help_c_abi_v2<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let param_types = Vec::from_iter_in(roc_function.get_type().get_param_types(), env.arena);
|
let param_types = Vec::from_iter_in(roc_function.get_type().get_param_types(), env.arena);
|
||||||
|
|
||||||
// drop the "return pointer" if it exists on the roc function
|
let (params, param_types) = match (&roc_return, &cc_return) {
|
||||||
// and the c function does not return via pointer
|
// Drop the "return pointer" if it exists on the roc function
|
||||||
let param_types = match (&roc_return, &cc_return) {
|
// and the c function does not return via pointer
|
||||||
(RocReturn::ByPointer, CCReturn::Return) => ¶m_types[1..],
|
(RocReturn::ByPointer, CCReturn::Return) => (¶ms[..], ¶m_types[1..]),
|
||||||
_ => ¶m_types,
|
// Drop the return pointer the other way, if the C function returns by pointer but Roc
|
||||||
|
// doesn't
|
||||||
|
(RocReturn::Return, CCReturn::ByPointer) => (¶ms[1..], ¶m_types[..]),
|
||||||
|
_ => (¶ms[..], ¶m_types[..]),
|
||||||
};
|
};
|
||||||
|
|
||||||
debug_assert_eq!(params.len(), param_types.len());
|
debug_assert_eq!(params.len(), param_types.len());
|
||||||
|
|
|
@ -648,4 +648,42 @@ mod test_load {
|
||||||
Ok(_) => unreachable!("we expect failure here"),
|
Ok(_) => unreachable!("we expect failure here"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
// See https://github.com/rtfeldman/roc/issues/2413
|
||||||
|
fn platform_exposes_main_return_by_pointer_issue() {
|
||||||
|
let modules = vec![
|
||||||
|
(
|
||||||
|
"platform/Package-Config.roc",
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
platform "examples/hello-world"
|
||||||
|
requires {} { main : { content: Str, other: Str } }
|
||||||
|
exposes []
|
||||||
|
packages {}
|
||||||
|
imports []
|
||||||
|
provides [ mainForHost ]
|
||||||
|
|
||||||
|
mainForHost : { content: Str, other: Str }
|
||||||
|
mainForHost = main
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Main",
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "hello-world"
|
||||||
|
packages { pf: "platform" }
|
||||||
|
imports []
|
||||||
|
provides [ main ] to pf
|
||||||
|
|
||||||
|
main = { content: "Hello, World!\n", other: "" }
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
assert!(multiple_modules(modules).is_ok());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue