Skip to content

Commit d70144b

Browse files
committed
Wrap [VaList] in Box to be able to use it as FnPtrArg
1 parent 8503629 commit d70144b

38 files changed

Lines changed: 560 additions & 196 deletions

‎cpp2rust/converter/converter.cpp‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,9 @@ Converter::ConvertFunctionPointerType(const clang::FunctionProtoType *proto) {
295295
result += ToString(p_ty);
296296
result += ',';
297297
}
298+
if (proto->isVariadic()) {
299+
result += "Box<[VaArg]>,";
300+
}
298301
result += ')';
299302
if (!proto->getReturnType()->isVoidType()) {
300303
result += std::format(" -> {}", ToString(proto->getReturnType()));
@@ -2216,8 +2219,9 @@ void Converter::EmitArgList(const CallInfo &info) {
22162219

22172220
if (info.is_variadic) {
22182221
if (!info.is_libc_passthrough) {
2219-
StrCat(token::kRef);
2222+
StrCat("Box::new");
22202223
}
2224+
PushParen box(*this, !info.is_libc_passthrough);
22212225
PushBracket push(*this, !info.is_libc_passthrough);
22222226
for (auto *arg : info.variadic_args) {
22232227
{
@@ -4044,6 +4048,9 @@ void Converter::ConvertLambdaClosure(const clang::CXXRecordDecl *decl,
40444048
ConvertVarDeclSkipInit(p);
40454049
StrCat(token::kComma);
40464050
}
4051+
if (call_operator->isVariadic()) {
4052+
StrCat("__args: Box<[VaArg]>", token::kComma);
4053+
}
40474054
in_function_formals_ = false;
40484055
StrCat('|');
40494056
ConvertFunctionReturnType(call_operator);
@@ -4605,7 +4612,7 @@ void Converter::ConvertFunctionParameters(clang::FunctionDecl *decl) {
46054612
StrCat(token::kComma);
46064613
}
46074614
if (decl->isVariadic()) {
4608-
StrCat("__args: &[VaArg]", token::kComma);
4615+
StrCat("__args: Box<[VaArg]>", token::kComma);
46094616
}
46104617
in_function_formals_ = false;
46114618
}

‎libcc2rs/src/fn_ptr_arg.rs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::rc::Rc;
99

1010
use crate::rc::Ptr;
1111
use crate::reinterpret::ByteRepr;
12+
use crate::va_args::VaArg;
1213
use crate::void::{AnyPtr, ErasedPtr};
1314

1415
pub enum ArgRepr {
@@ -126,6 +127,16 @@ impl FnPtrArg for AnyPtr {
126127
}
127128
}
128129

130+
impl FnPtrArg for Box<[VaArg]> {
131+
#[inline]
132+
fn to_repr(self) -> ArgRepr {
133+
ArgRepr::Record(Box::new(self))
134+
}
135+
fn from_repr(r: ArgRepr) -> Self {
136+
record_from_repr(r)
137+
}
138+
}
139+
129140
impl<T: ?Sized + 'static> FnPtrArg for *mut T {
130141
#[inline]
131142
fn to_repr(self) -> ArgRepr {
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
extern crate libcc2rs;
2+
use libcc2rs::*;
3+
use std::cell::RefCell;
4+
use std::collections::BTreeMap;
5+
use std::io::prelude::*;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::AsFd;
8+
use std::rc::{Rc, Weak};
9+
pub fn apply_0(mut x: i32, mut fn_: FnPtr<fn(i32) -> i32>) -> i32 {
10+
return ({ fn_.call(x) });
11+
}
12+
pub fn call_nttp_1(mut x: i32) -> i32 {
13+
return ({
14+
(FnPtr::<fn(i32) -> i32>::new(|mut x: i32| -> i32 {
15+
{
16+
return (x - 1);
17+
}
18+
}))
19+
.call(x)
20+
});
21+
}
22+
pub fn call_nttp_2(mut x: i32) -> i32 {
23+
return ({
24+
(FnPtr::<fn(i32) -> i32>::new(|mut x: i32| -> i32 {
25+
{
26+
return (x * 10);
27+
}
28+
}))
29+
.call(x)
30+
});
31+
}
32+
pub fn call_nttp_3(mut x: i32) -> i32 {
33+
return ({
34+
FnPtr::<fn(i32) -> i32>::new(|mut x: i32| -> i32 {
35+
{
36+
return (x + 100);
37+
}
38+
})
39+
.call(x)
40+
});
41+
}
42+
pub fn main() {
43+
__cpp2rust_init_globals();
44+
std::process::exit(main_0());
45+
}
46+
fn main_0() -> i32 {
47+
let mut fresh: FnPtr<fn(i32) -> i32> = FnPtr::<fn(i32) -> i32>::new(|mut x: i32| -> i32 {
48+
{
49+
return -x;
50+
}
51+
});
52+
assert!((({ fresh.call(5,) }) == -5_i32));
53+
let twice: Value<FnPtr<fn(i32) -> i32>> = Rc::new(RefCell::new(FnPtr::<fn(i32) -> i32>::new(
54+
|mut x: i32| -> i32 {
55+
{
56+
return (x * 2);
57+
}
58+
},
59+
)));
60+
let mut named: FnPtr<fn(i32) -> i32> = (*twice.borrow()).clone();
61+
assert!((({ named.call(5,) }) == 10));
62+
assert!((({ apply_0(5, (*twice.borrow()).clone(),) }) == 10));
63+
named = (fresh).clone();
64+
assert!((({ named.call(3,) }) == -3_i32));
65+
let mut p: FnPtr<fn(i32) -> i32> = FnPtr::<fn(i32) -> i32>::new(|mut x: i32| -> i32 {
66+
{
67+
return (x * 3);
68+
}
69+
});
70+
assert!((({ p.call(2,) }) == 6));
71+
assert!((({ call_nttp_1(5,) }) == 4));
72+
assert!((({ call_nttp_2(5,) }) == 50));
73+
assert!((({ call_nttp_3(5,) }) == 105));
74+
let sum: Value<FnPtr<fn(i32, Box<[VaArg]>) -> i32>> =
75+
Rc::new(RefCell::new(FnPtr::<fn(i32, Box<[VaArg]>) -> i32>::new(
76+
|n: i32, __args: Box<[VaArg]>| -> i32 {
77+
{
78+
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
79+
let n: Value<i32> = Rc::new(RefCell::new(n));
80+
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
81+
(*ap.borrow_mut()) = __args.as_pointer();
82+
let s: Value<i32> = Rc::new(RefCell::new(0));
83+
let mut i: i32 = 0;
84+
'loop_: while (i < (*n.borrow())) {
85+
(*s.borrow_mut()) += (*ap.borrow_mut()).arg::<i32>();
86+
i.postfix_inc();
87+
}
88+
return (*s.borrow());
89+
}
90+
},
91+
)));
92+
assert!((({ (*sum.borrow()).call(2, Box::new([(5).into(), (5).into(),])) }) == 10));
93+
assert!((({ (*sum.borrow()).call(3, Box::new([(1).into(), (2).into(), (3).into(),])) }) == 6));
94+
return 0;
95+
}
96+
pub fn __cpp2rust_init_globals() {}

‎tests/unit/out/refcount/va_arg_chain.rs‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub fn middle_layer_1(mut n: i32, ap: Ptr<VaArg>) -> i32 {
1919
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(ap));
2020
return ({ extract_nth_0(n, (*ap.borrow()).clone()) });
2121
}
22-
pub fn top_level_2(n: i32, __args: &[VaArg]) -> i32 {
22+
pub fn top_level_2(n: i32, __args: Box<[VaArg]>) -> i32 {
2323
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
2424
let n: Value<i32> = Rc::new(RefCell::new(n));
2525
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
@@ -34,13 +34,21 @@ pub fn main() {
3434
fn main_0() -> i32 {
3535
assert!(
3636
(((({
37-
top_level_2(2, &[(100).into(), (200).into(), (300).into(), (400).into()])
37+
top_level_2(
38+
2,
39+
Box::new([(100).into(), (200).into(), (300).into(), (400).into()]),
40+
)
3841
}) == 300) as i32)
3942
!= 0)
4043
);
41-
assert!((((({ top_level_2(0, &[(42).into(), (99).into(),]) }) == 42) as i32) != 0));
44+
assert!((((({ top_level_2(0, Box::new([(42).into(), (99).into(),])) }) == 42) as i32) != 0));
4245
assert!(
43-
(((({ top_level_2(3, &[(1).into(), (2).into(), (3).into(), (4).into(),]) }) == 4) as i32)
46+
(((({
47+
top_level_2(
48+
3,
49+
Box::new([(1).into(), (2).into(), (3).into(), (4).into()]),
50+
)
51+
}) == 4) as i32)
4452
!= 0)
4553
);
4654
return 0;

‎tests/unit/out/refcount/va_arg_concat.rs‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::io::prelude::*;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::AsFd;
88
use std::rc::{Rc, Weak};
9-
pub fn sum_ints_0(first: i32, __args: &[VaArg]) -> i32 {
9+
pub fn sum_ints_0(first: i32, __args: Box<[VaArg]>) -> i32 {
1010
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
1111
let first: Value<i32> = Rc::new(RefCell::new(first));
1212
let args: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
@@ -29,15 +29,20 @@ pub fn main() {
2929
}
3030
fn main_0() -> i32 {
3131
assert!(
32-
(((({ sum_ints_0(1, &[(2).into(), (3).into(), (4).into(), (0).into(),]) }) == 10) as i32)
32+
(((({
33+
sum_ints_0(
34+
1,
35+
Box::new([(2).into(), (3).into(), (4).into(), (0).into()]),
36+
)
37+
}) == 10) as i32)
3338
!= 0)
3439
);
35-
assert!((((({ sum_ints_0(100, &[(0).into(),]) }) == 100) as i32) != 0));
40+
assert!((((({ sum_ints_0(100, Box::new([(0).into(),])) }) == 100) as i32) != 0));
3641
assert!(
3742
(((({
3843
sum_ints_0(
3944
5,
40-
&[(5).into(), (5).into(), (5).into(), (5).into(), (0).into()],
45+
Box::new([(5).into(), (5).into(), (5).into(), (5).into(), (0).into()]),
4146
)
4247
}) == 25) as i32)
4348
!= 0)

‎tests/unit/out/refcount/va_arg_conditional.rs‎

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::io::prelude::*;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::AsFd;
88
use std::rc::{Rc, Weak};
9-
pub fn conditional_log_0(mut verbose: i32, fmt: Ptr<i8>, __args: &[VaArg]) -> i32 {
9+
pub fn conditional_log_0(mut verbose: i32, fmt: Ptr<i8>, __args: Box<[VaArg]>) -> i32 {
1010
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
1111
let fmt: Value<Ptr<i8>> = Rc::new(RefCell::new(fmt));
1212
if (verbose != 0) {
@@ -23,13 +23,23 @@ pub fn main() {
2323
}
2424
fn main_0() -> i32 {
2525
assert!(
26-
(((({ conditional_log_0(1, Ptr::<i8>::from_string_literal(b"%d"), &[(42).into(),]) }) == 42)
27-
as i32)
26+
(((({
27+
conditional_log_0(
28+
1,
29+
Ptr::<i8>::from_string_literal(b"%d"),
30+
Box::new([(42).into()]),
31+
)
32+
}) == 42) as i32)
2833
!= 0)
2934
);
3035
assert!(
31-
(((({ conditional_log_0(0, Ptr::<i8>::from_string_literal(b"%d"), &[(99).into(),]) })
32-
== -1_i32) as i32)
36+
(((({
37+
conditional_log_0(
38+
0,
39+
Ptr::<i8>::from_string_literal(b"%d"),
40+
Box::new([(99).into()]),
41+
)
42+
}) == -1_i32) as i32)
3343
!= 0)
3444
);
3545
return 0;

‎tests/unit/out/refcount/va_arg_copy.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::io::prelude::*;
66
use std::io::{Read, Seek, Write};
77
use std::os::fd::AsFd;
88
use std::rc::{Rc, Weak};
9-
pub fn sum_with_copy_0(count: i32, __args: &[VaArg]) -> i32 {
9+
pub fn sum_with_copy_0(count: i32, __args: Box<[VaArg]>) -> i32 {
1010
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
1111
let count: Value<i32> = Rc::new(RefCell::new(count));
1212
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
@@ -34,7 +34,8 @@ pub fn main() {
3434
}
3535
fn main_0() -> i32 {
3636
assert!(
37-
(((({ sum_with_copy_0(3, &[(10).into(), (20).into(), (30).into(),]) }) == 120) as i32)
37+
(((({ sum_with_copy_0(3, Box::new([(10).into(), (20).into(), (30).into(),])) }) == 120)
38+
as i32)
3839
!= 0)
3940
);
4041
return 0;

‎tests/unit/out/refcount/va_arg_fn_ptr.rs‎

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub fn negate_1(mut x: i32) -> i32 {
1515
pub fn add_2(mut a: i32, mut b: i32) -> i32 {
1616
return (a + b);
1717
}
18-
pub fn apply_unary_3(x: i32, __args: &[VaArg]) -> i32 {
18+
pub fn apply_unary_3(x: i32, __args: Box<[VaArg]>) -> i32 {
1919
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
2020
let x: Value<i32> = Rc::new(RefCell::new(x));
2121
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
@@ -24,7 +24,7 @@ pub fn apply_unary_3(x: i32, __args: &[VaArg]) -> i32 {
2424
let mut result: i32 = ({ fn_.call((*x.borrow())) });
2525
return result;
2626
}
27-
pub fn apply_binary_4(mut a: i32, b: i32, __args: &[VaArg]) -> i32 {
27+
pub fn apply_binary_4(mut a: i32, b: i32, __args: Box<[VaArg]>) -> i32 {
2828
let __args: Value<Box<[VaArg]>> = Rc::new(RefCell::new(__args.into()));
2929
let b: Value<i32> = Rc::new(RefCell::new(b));
3030
let ap: Value<Ptr<VaArg>> = Rc::new(RefCell::new(Ptr::<VaArg>::default()));
@@ -46,18 +46,31 @@ pub fn main() {
4646
}
4747
fn main_0() -> i32 {
4848
assert!(
49-
(((({ apply_unary_3(5, &[(FnPtr::<fn(i32) -> i32>::new(square_0)).into(),]) }) == 25)
50-
as i32)
49+
(((({
50+
apply_unary_3(
51+
5,
52+
Box::new([(FnPtr::<fn(i32) -> i32>::new(square_0)).into()]),
53+
)
54+
}) == 25) as i32)
5155
!= 0)
5256
);
5357
assert!(
54-
(((({ apply_unary_3(7, &[(FnPtr::<fn(i32) -> i32>::new(negate_1)).into(),]) }) == -7_i32)
55-
as i32)
58+
(((({
59+
apply_unary_3(
60+
7,
61+
Box::new([(FnPtr::<fn(i32) -> i32>::new(negate_1)).into()]),
62+
)
63+
}) == -7_i32) as i32)
5664
!= 0)
5765
);
5866
assert!(
59-
(((({ apply_binary_4(3, 4, &[(FnPtr::<fn(i32, i32) -> i32>::new(add_2)).into(),]) }) == 7)
60-
as i32)
67+
(((({
68+
apply_binary_4(
69+
3,
70+
4,
71+
Box::new([(FnPtr::<fn(i32, i32) -> i32>::new(add_2)).into()]),
72+
)
73+
}) == 7) as i32)
6174
!= 0)
6275
);
6376
let dummy: Value<i32> = Rc::new(RefCell::new(0));
@@ -69,17 +82,28 @@ fn main_0() -> i32 {
6982
}) == -3_i32) as i32)
7083
!= 0)
7184
);
72-
let mut vu: FnPtr<fn(i32) -> i32> = FnPtr::<fn(i32) -> i32>::new(apply_unary_3);
85+
let mut vu: FnPtr<fn(i32, Box<[VaArg]>) -> i32> =
86+
FnPtr::<fn(i32, Box<[VaArg]>) -> i32>::new(apply_unary_3);
7387
assert!(
74-
(((({ vu.call(6, &[(FnPtr::<fn(i32) -> i32>::new(square_0)).into(),]) }) == 36) as i32)
88+
(((({
89+
vu.call(
90+
6,
91+
Box::new([(FnPtr::<fn(i32) -> i32>::new(square_0)).into()]),
92+
)
93+
}) == 36) as i32)
7594
!= 0)
7695
);
77-
let mut vb: FnPtr<fn(i32, i32) -> i32> =
78-
FnPtr::<fn(i32) -> i32>::new(apply_unary_3).cast::<fn(i32, i32) -> i32>();
79-
vu = vb.cast::<fn(i32) -> i32>();
96+
let mut vb: FnPtr<fn(i32, i32, Box<[VaArg]>) -> i32> =
97+
FnPtr::<fn(i32, Box<[VaArg]>) -> i32>::new(apply_unary_3)
98+
.cast::<fn(i32, i32, Box<[VaArg]>) -> i32>();
99+
vu = vb.cast::<fn(i32, Box<[VaArg]>) -> i32>();
80100
assert!(
81-
(((({ vu.call(2, &[(FnPtr::<fn(i32) -> i32>::new(negate_1)).into(),]) }) == -2_i32)
82-
as i32)
101+
(((({
102+
vu.call(
103+
2,
104+
Box::new([(FnPtr::<fn(i32) -> i32>::new(negate_1)).into()]),
105+
)
106+
}) == -2_i32) as i32)
83107
!= 0)
84108
);
85109
return 0;

0 commit comments

Comments
 (0)