mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
allow passing of RocStr by-value from a host
This commit is contained in:
parent
e79543aac7
commit
2762457e10
1 changed files with 31 additions and 0 deletions
|
@ -3718,6 +3718,37 @@ fn expose_function_to_host_help_c_abi_v2<'a, 'ctx, 'env>(
|
|||
Linkage::External,
|
||||
);
|
||||
|
||||
// a temporary solution to be able to pass RocStr by-value from a host language.
|
||||
{
|
||||
let extra = match cc_return {
|
||||
CCReturn::Return => 0,
|
||||
CCReturn::ByPointer => 1,
|
||||
CCReturn::Void => 0,
|
||||
};
|
||||
|
||||
for (i, layout) in arguments.iter().enumerate() {
|
||||
if let Layout::Builtin(Builtin::Str) = layout {
|
||||
// Indicate to LLVM that this argument is semantically passed by-value
|
||||
// even though technically (because of its size) it is passed by-reference
|
||||
let byval_attribute_id = Attribute::get_named_enum_kind_id("byval");
|
||||
debug_assert!(byval_attribute_id > 0);
|
||||
|
||||
// if ret_typ is a pointer type. We need the base type here.
|
||||
let ret_typ = c_function.get_type().get_param_types()[i + extra];
|
||||
let ret_base_typ = if ret_typ.is_pointer_type() {
|
||||
ret_typ.into_pointer_type().get_element_type()
|
||||
} else {
|
||||
ret_typ.as_any_type_enum()
|
||||
};
|
||||
|
||||
let byval_attribute = env
|
||||
.context
|
||||
.create_type_attribute(byval_attribute_id, ret_base_typ);
|
||||
c_function.add_attribute(AttributeLoc::Param((i + extra) as u32), byval_attribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let subprogram = env.new_subprogram(c_function_name);
|
||||
c_function.set_subprogram(subprogram);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue