Skip to content

Commit d1129ed

Browse files
committed
[bindings] Update eq/clone trait fns to take object, not this_arg
When a trait is required to implement eq/clone (eg in the case of `SocketDescriptor`), the generated trait struct contains an eq/clone function which takes a `this_arg` pointer. Since the trait object can always be read to get the `this_arg` pointer, there is no loss of generality to pass the trait object itself, and it provides a bit more flexibility when the trait could be one of several implementations (which we use in the Java higher-level bindings).
1 parent c1c21a1 commit d1129ed

File tree

2 files changed

+15
-10
lines changed

2 files changed

+15
-10
lines changed

c-bindings-gen/src/main.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
226226
generated_fields.push("clone".to_owned());
227227
},
228228
("std::cmp::Eq", _) => {
229-
writeln!(w, "\tpub eq: extern \"C\" fn (this_arg: *const c_void, other_arg: *const c_void) -> bool,").unwrap();
229+
writeln!(w, "\tpub eq: extern \"C\" fn (this_arg: *const c_void, other_arg: &{}) -> bool,", trait_name).unwrap();
230+
writeln!(extra_headers, "typedef struct LDK{} LDK{};", trait_name, trait_name).unwrap();
230231
generated_fields.push("eq".to_owned());
231232
},
232233
("std::hash::Hash", _) => {
@@ -251,21 +252,25 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
251252
("std::cmp::Eq", _) => {
252253
writeln!(w, "impl std::cmp::Eq for {} {{}}", trait_name).unwrap();
253254
writeln!(w, "impl std::cmp::PartialEq for {} {{", trait_name).unwrap();
254-
writeln!(w, "\tfn eq(&self, o: &Self) -> bool {{ (self.eq)(self.this_arg, o.this_arg) }}\n}}").unwrap();
255+
writeln!(w, "\tfn eq(&self, o: &Self) -> bool {{ (self.eq)(self.this_arg, o) }}\n}}").unwrap();
255256
},
256257
("std::hash::Hash", _) => {
257258
writeln!(w, "impl std::hash::Hash for {} {{", trait_name).unwrap();
258259
writeln!(w, "\tfn hash<H: std::hash::Hasher>(&self, hasher: &mut H) {{ hasher.write_u64((self.hash)(self.this_arg)) }}\n}}").unwrap();
259260
},
260261
("Clone", _) => {
261-
writeln!(w, "impl Clone for {} {{", trait_name).unwrap();
262-
writeln!(w, "\tfn clone(&self) -> Self {{").unwrap();
263-
writeln!(w, "\t\tSelf {{").unwrap();
264-
writeln!(w, "\t\tthis_arg: if let Some(f) = self.clone {{ (f)(self.this_arg) }} else {{ self.this_arg }},").unwrap();
262+
writeln!(w, "#[no_mangle]").unwrap();
263+
writeln!(w, "pub extern \"C\" fn {}_clone(orig: &{}) -> {} {{", trait_name, trait_name, trait_name).unwrap();
264+
writeln!(w, "\t{} {{", trait_name).unwrap();
265+
writeln!(w, "\t\tthis_arg: if let Some(f) = orig.clone {{ (f)(orig.this_arg) }} else {{ orig.this_arg }},").unwrap();
265266
for field in generated_fields.iter() {
266-
writeln!(w, "\t\t\t{}: self.{}.clone(),", field, field).unwrap();
267+
writeln!(w, "\t\t{}: orig.{}.clone(),", field, field).unwrap();
267268
}
268-
writeln!(w, "\t\t}}\n\t}}\n}}").unwrap();
269+
writeln!(w, "\t}}\n}}").unwrap();
270+
writeln!(w, "impl Clone for {} {{", trait_name).unwrap();
271+
writeln!(w, "\tfn clone(&self) -> Self {{").unwrap();
272+
writeln!(w, "\t\t{}_clone(self)", trait_name).unwrap();
273+
writeln!(w, "\t}}\n}}").unwrap();
269274
},
270275
(s, i) => {
271276
if s != "util::events::MessageSendEventsProvider" { unimplemented!(); }

lightning-c-bindings/demo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
191191
void sock_disconnect_socket(void *this_arg) {
192192
close((int)((long)this_arg));
193193
}
194-
bool sock_eq(const void *this_arg, const void *other_arg) {
195-
return this_arg == other_arg;
194+
bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
195+
return this_arg == other_arg->this_arg;
196196
}
197197
uint64_t sock_hash(const void *this_arg) {
198198
return (uint64_t)this_arg;

0 commit comments

Comments
 (0)