Skip to content

Commit 12250cc

Browse files
committed
Delete lambda field from FnPtr
1 parent e1ad0cb commit 12250cc

1 file changed

Lines changed: 25 additions & 24 deletions

File tree

‎libcc2rs/src/fn_ptr.rs‎

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ impl<T: FnSig> Adapted for T {
6060
}
6161
}
6262

63+
struct Closure<T: FnSig>(Box<dyn Fn(T::Args) -> T::Ret>);
64+
65+
impl<T: FnSig> Adapted for Closure<T> {
66+
fn call_adapted(&self, args: ArgList<'_>, sink: &mut dyn FnMut(ArgRepr<'_>)) {
67+
let converted_args = T::Args::from_list(&args);
68+
let result = (self.0)(converted_args);
69+
sink(result.to_repr());
70+
}
71+
}
72+
6373
pub struct FnPtr<T: FnSig> {
6474
// Address of the function this pointer was created from. 0 for null,
6575
// which is never the address of a function.
@@ -71,7 +81,6 @@ pub struct FnPtr<T: FnSig> {
7181
// The function this pointer was created from, kept type-erased (but
7282
// still callable, through `Adapted`).
7383
original: Option<Rc<dyn Adapted>>,
74-
lambda: Option<Rc<dyn Fn(T::Args) -> T::Ret>>,
7584
}
7685

7786
impl<T: FnSig> FnPtr<T> {
@@ -81,7 +90,6 @@ impl<T: FnSig> FnPtr<T> {
8190
addr: 0,
8291
current: None,
8392
original: None,
84-
lambda: None,
8593
}
8694
}
8795

@@ -96,7 +104,6 @@ impl<T: FnSig> FnPtr<T> {
96104
addr: f.fn_addr(),
97105
current: Some(f),
98106
original: None,
99-
lambda: None,
100107
}
101108
}
102109

@@ -107,13 +114,14 @@ impl<T: FnSig> FnPtr<T> {
107114
if self.is_null() {
108115
panic!("ub: null fn pointer call");
109116
}
110-
if let Some(lambda) = &self.lambda {
111-
return lambda(args);
112-
}
113117
if let Some(f) = self.current {
114118
return f.call_direct(args);
115119
}
116120
if let Some(original) = &self.original {
121+
let closure: &dyn Any = &**original;
122+
if let Some(closure) = closure.downcast_ref::<Closure<T>>() {
123+
return (closure.0)(args);
124+
}
117125
let mut result = None;
118126
original.call_adapted(args.to_list(), &mut |repr| {
119127
result = Some(T::Ret::from_repr(&repr));
@@ -152,17 +160,10 @@ impl<T: FnSig> FnPtr<T> {
152160
self.boxed_original()
153161
};
154162

155-
let lambda: &dyn Any = &self.lambda;
156-
let lambda = lambda
157-
.downcast_ref::<Option<Rc<dyn Fn(U::Args) -> U::Ret>>>()
158-
.cloned()
159-
.flatten();
160-
161163
FnPtr {
162164
addr: self.addr,
163165
current: current_as_u.or(original_as_u),
164166
original,
165-
lambda,
166167
}
167168
}
168169

@@ -195,14 +196,13 @@ macro_rules! impl_fn_ptr_call {
195196
lambda: Lambda,
196197
call: fn(&Lambda $(, $a)*) -> R,
197198
) -> Self {
198-
let lambda = Rc::new(lambda);
199+
let closure: Rc<dyn Adapted> = Rc::new(Closure::<fn($($a,)*) -> R>(
200+
Box::new(move |($($a,)*): ($($a,)*)| call(&lambda $(, $a)*)),
201+
));
199202
FnPtr {
200203
addr: call as usize,
201204
current: None,
202-
original: None,
203-
lambda: Some(Rc::new(move |($($a,)*): ($($a,)*)| {
204-
call(&lambda $(, $a)*)
205-
})),
205+
original: Some(closure),
206206
}
207207
}
208208

@@ -211,14 +211,16 @@ macro_rules! impl_fn_ptr_call {
211211
lambda: Lambda,
212212
call: fn(&mut Lambda $(, $a)*) -> R,
213213
) -> Self {
214-
let lambda = Rc::new(UnsafeCell::new(lambda));
214+
let lambda = UnsafeCell::new(lambda);
215+
let closure: Rc<dyn Adapted> = Rc::new(Closure::<fn($($a,)*) -> R>(
216+
Box::new(move |($($a,)*): ($($a,)*)| {
217+
call(unsafe { &mut *lambda.get() } $(, $a)*)
218+
}),
219+
));
215220
FnPtr {
216221
addr: call as usize,
217222
current: None,
218-
original: None,
219-
lambda: Some(Rc::new(move |($($a,)*): ($($a,)*)| {
220-
call(unsafe { &mut *lambda.get() } $(, $a)*)
221-
})),
223+
original: Some(closure),
222224
}
223225
}
224226
}
@@ -237,7 +239,6 @@ impl<T: FnSig> Clone for FnPtr<T> {
237239
addr: self.addr,
238240
current: self.current,
239241
original: self.original.clone(),
240-
lambda: self.lambda.clone(),
241242
}
242243
}
243244
}

0 commit comments

Comments
 (0)