Skip to content

Commit 1b0458c

Browse files
committed
Use pointers for the C definitions to resolve ABI inconsistencies
1 parent 6ef8b8f commit 1b0458c

3 files changed

Lines changed: 29 additions & 12 deletions

File tree

crates/intrinsic-test/src/common/argument.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,21 @@ where
8989
pub fn as_non_imm_arglist_c(&self) -> String {
9090
self.iter()
9191
.filter(|arg| !arg.has_constraint())
92-
.format_with(", ", |arg, fmt| {
93-
fmt(&format_args!("{} {}", arg.to_c_type(), arg.name))
92+
.format_with("", |arg, fmt| {
93+
fmt(&format_args!(", const {}* {}", arg.to_c_type(), arg.name))
9494
})
9595
.to_string()
9696
}
9797

9898
pub fn as_non_imm_arglist_rust(&self) -> String {
9999
self.iter()
100100
.filter(|arg| !arg.has_constraint())
101-
.format_with(", ", |arg, fmt| {
102-
fmt(&format_args!("{}: {}", arg.name, arg.ty.rust_type()))
101+
.format_with("", |arg, fmt| {
102+
fmt(&format_args!(
103+
", {}: *const {}",
104+
arg.name,
105+
arg.ty.rust_type()
106+
))
103107
})
104108
.to_string()
105109
}
@@ -111,6 +115,7 @@ where
111115
if arg.has_constraint() {
112116
fmt(&imm_args.next().unwrap())
113117
} else {
118+
fmt(&"*")?;
114119
fmt(&arg.name)
115120
}
116121
})
@@ -126,6 +131,13 @@ where
126131
.join(", ")
127132
}
128133

134+
pub fn as_c_call_param_rust(&self) -> String {
135+
self.iter()
136+
.filter(|a| !a.has_constraint())
137+
.map(|arg| format!(", &raw const {} as _", arg.generate_name()))
138+
.join("")
139+
}
140+
129141
/// Creates a line for each argument that initializes an array for Rust from which `loads` argument
130142
/// values can be loaded as a sliding window, e.g `const A_VALS: [u32; 20] = [...];`
131143
pub fn gen_arglists_rust(

crates/intrinsic-test/src/common/gen_c.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ pub fn write_wrapper_c<T: IntrinsicTypeDefinition>(
2424
writeln!(
2525
w,
2626
"
27-
{return_ty} {name}_wrapper{imm_arglist}({arglist}) {{
28-
return {name}({params});
27+
void {name}_wrapper{imm_arglist}({return_ty}* dst{arglist}) {{
28+
*dst = {name}({params});
2929
}}",
3030
return_ty = intrinsic.results.c_type(),
3131
name = intrinsic.name,

crates/intrinsic-test/src/common/gen_rust.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,13 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
130130

131131
// Each function (and each specialization) has its own type. Erase that type with a cast.
132132
let mut coerce = String::from("fn(");
133+
let mut c_coerce = String::from("fn(_, ");
133134
for _ in intrinsic.arguments.iter().filter(|a| !a.has_constraint()) {
134135
coerce += "_, ";
136+
c_coerce += "_, ";
135137
}
136138
coerce += ") -> _";
139+
c_coerce += ")";
137140

138141
if intrinsic
139142
.arguments
@@ -152,7 +155,7 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
152155
intrinsic.iter_specializations(|imm_values| {
153156
writeln!(
154157
w,
155-
" (\"{const_args}\", {intrinsic_name}::<{const_args}> as unsafe {coerce}, {intrinsic_name}_wrapper_{c_const_args} as unsafe extern \"C\" {coerce}),",
158+
" (\"{const_args}\", {intrinsic_name}::<{const_args}> as unsafe {coerce}, {intrinsic_name}_wrapper_{c_const_args} as unsafe extern \"C\" {c_coerce}),",
156159
const_args = imm_values.iter().join(","),
157160
c_const_args = imm_values.iter().join("_"),
158161
)
@@ -191,17 +194,19 @@ fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
191194
" for i in 0..{passes} {{",
192195
" unsafe {{",
193196
"{loaded_args}",
194-
" let __rust_return_value = rust({args});",
195-
" let __c_return_value = c({args});",
196-
" assert_eq!({cast_prefix}__rust_return_value{cast_suffix}, {cast_prefix}__c_return_value{cast_suffix}, \"{{id}}\");",
197+
" let __rust_return_value = rust({rust_args});",
198+
" let mut __c_return_value = std::mem::MaybeUninit::uninit();",
199+
" c(__c_return_value.as_mut_ptr(){c_args});",
200+
" assert_eq!({cast_prefix}__rust_return_value{cast_suffix}, {cast_prefix}__c_return_value.assume_init(){cast_suffix}, \"{{id}}\");",
197201
" }}",
198202
" }}",
199203
" }}",
200204
),
201205
loaded_args = intrinsic
202206
.arguments
203207
.load_values_rust(Indentation::default().nest_by(4)),
204-
args = intrinsic.arguments.as_call_param_rust(),
208+
rust_args = intrinsic.arguments.as_call_param_rust(),
209+
c_args = intrinsic.arguments.as_c_call_param_rust(),
205210
passes = passes,
206211
cast_prefix = cast_prefix,
207212
cast_suffix = cast_suffix,
@@ -250,7 +255,7 @@ pub fn write_bindings_rust<T: IntrinsicTypeDefinition>(
250255
intrinsic.iter_specializations(|imm_values| {
251256
writeln!(
252257
w,
253-
" fn {name}_wrapper{imm_arglist}({arglist}) -> {return_ty};",
258+
" fn {name}_wrapper{imm_arglist}(dst: *mut {return_ty}{arglist});",
254259
return_ty = intrinsic.results.rust_type(),
255260
name = intrinsic.name,
256261
imm_arglist = imm_values

0 commit comments

Comments
 (0)