X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=c-bindings-gen%2Fsrc%2Fmain.rs;h=87ae6215ab7205a70c87f5620f9a11bc0dc82087;hb=379be5837d69fe90c5802dc1fc9178933529e0c5;hp=06050c5c8e8b84d31c89460c81e5a3f5d2bc19de;hpb=c0c17650327b5aedba389bd7428358e29670506e;p=ldk-c-bindings diff --git a/c-bindings-gen/src/main.rs b/c-bindings-gen/src/main.rs index 06050c5..87ae621 100644 --- a/c-bindings-gen/src/main.rs +++ b/c-bindings-gen/src/main.rs @@ -24,7 +24,7 @@ use std::fs::File; use std::io::{Read, Write}; use std::process; -use proc_macro2::{TokenTree, TokenStream, Span}; +use proc_macro2::Span; mod types; mod blocks; @@ -35,38 +35,6 @@ use blocks::*; // *** Manually-expanded conversions *** // ************************************* -/// Because we don't expand macros, any code that we need to generated based on their contents has -/// to be completely manual. In this case its all just serialization, so its not too hard. -fn convert_macro(w: &mut W, macro_path: &syn::Path, stream: &TokenStream, types: &TypeResolver) { - assert_eq!(macro_path.segments.len(), 1); - match &format!("{}", macro_path.segments.iter().next().unwrap().ident) as &str { - "impl_writeable" | "impl_writeable_len_match" => { - let struct_for = if let TokenTree::Ident(i) = stream.clone().into_iter().next().unwrap() { i } else { unimplemented!(); }; - if let Some(s) = types.maybe_resolve_ident(&struct_for) { - if !types.crate_types.opaques.get(&s).is_some() { return; } - writeln!(w, "#[no_mangle]").unwrap(); - writeln!(w, "/// Serialize the {} into a byte array which can be read by {}_read", struct_for, struct_for).unwrap(); - writeln!(w, "pub extern \"C\" fn {}_write(obj: &{}) -> crate::c_types::derived::CVec_u8Z {{", struct_for, struct_for).unwrap(); - writeln!(w, "\tcrate::c_types::serialize_obj(unsafe {{ &(*(*obj).inner) }})").unwrap(); - writeln!(w, "}}").unwrap(); - writeln!(w, "#[no_mangle]").unwrap(); - writeln!(w, "pub(crate) extern \"C\" fn {}_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z {{", struct_for).unwrap(); - writeln!(w, "\tcrate::c_types::serialize_obj(unsafe {{ &*(obj as *const native{}) }})", struct_for).unwrap(); - writeln!(w, "}}").unwrap(); - writeln!(w, "#[no_mangle]").unwrap(); - writeln!(w, "/// Read a {} from a byte array, created by {}_write", struct_for, struct_for).unwrap(); - writeln!(w, "pub extern \"C\" fn {}_read(ser: crate::c_types::u8slice) -> {} {{", struct_for, struct_for).unwrap(); - writeln!(w, "\tif let Ok(res) = crate::c_types::deserialize_obj(ser) {{").unwrap(); - writeln!(w, "\t\t{} {{ inner: Box::into_raw(Box::new(res)), is_owned: true }}", struct_for).unwrap(); - writeln!(w, "\t}} else {{").unwrap(); - writeln!(w, "\t\t{} {{ inner: std::ptr::null_mut(), is_owned: true }}", struct_for).unwrap(); - writeln!(w, "\t}}\n}}").unwrap(); - } - }, - _ => {}, - } -} - /// Convert "impl trait_path for for_ty { .. }" for manually-mapped types (ie (de)serialization) fn maybe_convert_trait_impl(w: &mut W, trait_path: &syn::Path, for_ty: &syn::Type, types: &mut TypeResolver, generics: &GenericTypes) { if let Some(t) = types.maybe_resolve_path(&trait_path, Some(generics)) { @@ -211,14 +179,9 @@ fn write_trait_impl_field_assign(w: &mut W, trait_path: &str, } /// Write out the impl block for a defined trait struct which has a supertrait -fn do_write_impl_trait(w: &mut W, trait_path: &str, trait_name: &syn::Ident, for_obj: &str) { +fn do_write_impl_trait(w: &mut W, trait_path: &str, _trait_name: &syn::Ident, for_obj: &str) { +eprintln!("{}", trait_path); match trait_path { - "util::events::MessageSendEventsProvider" => { - writeln!(w, "impl lightning::{} for {} {{", trait_path, for_obj).unwrap(); - writeln!(w, "\tfn get_and_clear_pending_msg_events(&self) -> Vec {{").unwrap(); - writeln!(w, "\t\t::get_and_clear_pending_msg_events(&self.{})", trait_path, trait_path, trait_name).unwrap(); - writeln!(w, "\t}}\n}}").unwrap(); - }, "util::ser::Writeable" => { writeln!(w, "impl lightning::{} for {} {{", trait_path, for_obj).unwrap(); writeln!(w, "\tfn write(&self, w: &mut W) -> Result<(), ::std::io::Error> {{").unwrap(); @@ -837,12 +800,12 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ if let syn::Type::Reference(r) = &**rtype { write!(w, "\n\t\t{}{}: ", $indent, $m.sig.ident).unwrap(); types.write_empty_rust_val(Some(&gen_types), w, &*r.elem); - writeln!(w, ",\n{}\t\tset_{}: Some({}_{}_set_{}),", $indent, $m.sig.ident, ident, trait_obj.ident, $m.sig.ident).unwrap(); + writeln!(w, ",\n{}\t\tset_{}: Some({}_{}_set_{}),", $indent, $m.sig.ident, ident, $trait.ident, $m.sig.ident).unwrap(); printed = true; } } if !printed { - write!(w, "{}\t\t{}: {}_{}_{},\n", $indent, $m.sig.ident, ident, trait_obj.ident, $m.sig.ident).unwrap(); + write!(w, "{}\t\t{}: {}_{}_{},\n", $indent, $m.sig.ident, ident, $trait.ident, $m.sig.ident).unwrap(); } } } @@ -902,7 +865,7 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ if let syn::ReturnType::Type(_, _) = &$m.sig.output { writeln!(w, "#[must_use]").unwrap(); } - write!(w, "extern \"C\" fn {}_{}_{}(", ident, trait_obj.ident, $m.sig.ident).unwrap(); + write!(w, "extern \"C\" fn {}_{}_{}(", ident, $trait.ident, $m.sig.ident).unwrap(); gen_types.push_ctx(); assert!(gen_types.learn_generics(&$m.sig.generics, types)); write_method_params(w, &$m.sig, "c_void", types, Some(&gen_types), true, true); @@ -943,13 +906,13 @@ fn writeln_impl(w: &mut W, i: &syn::ItemImpl, types: &mut Typ if let syn::ReturnType::Type(_, rtype) = &$m.sig.output { if let syn::Type::Reference(r) = &**rtype { assert_eq!($m.sig.inputs.len(), 1); // Must only take self - writeln!(w, "extern \"C\" fn {}_{}_set_{}(trait_self_arg: &{}) {{", ident, trait_obj.ident, $m.sig.ident, trait_obj.ident).unwrap(); + writeln!(w, "extern \"C\" fn {}_{}_set_{}(trait_self_arg: &{}) {{", ident, $trait.ident, $m.sig.ident, $trait.ident).unwrap(); writeln!(w, "\t// This is a bit race-y in the general case, but for our specific use-cases today, we're safe").unwrap(); writeln!(w, "\t// Specifically, we must ensure that the first time we're called it can never be in parallel").unwrap(); write!(w, "\tif ").unwrap(); types.write_empty_rust_val_check(Some(&gen_types), w, &*r.elem, &format!("trait_self_arg.{}", $m.sig.ident)); writeln!(w, " {{").unwrap(); - writeln!(w, "\t\tunsafe {{ &mut *(trait_self_arg as *const {} as *mut {}) }}.{} = {}_{}_{}(trait_self_arg.this_arg);", trait_obj.ident, trait_obj.ident, $m.sig.ident, ident, trait_obj.ident, $m.sig.ident).unwrap(); + writeln!(w, "\t\tunsafe {{ &mut *(trait_self_arg as *const {} as *mut {}) }}.{} = {}_{}_{}(trait_self_arg.this_arg);", $trait.ident, $trait.ident, $m.sig.ident, ident, $trait.ident, $m.sig.ident).unwrap(); writeln!(w, "\t}}").unwrap(); writeln!(w, "}}").unwrap(); } @@ -1501,11 +1464,7 @@ fn convert_file<'a, 'b>(libast: &'a FullLibraryAST, crate_types: &mut CrateTypes writeln_fn(&mut out, &f, &mut type_resolver); } }, - syn::Item::Macro(m) => { - if m.ident.is_none() { // If its not a macro definition - convert_macro(&mut out, &m.mac.path, &m.mac.tokens, &type_resolver); - } - }, + syn::Item::Macro(_) => {}, syn::Item::Verbatim(_) => {}, syn::Item::ExternCrate(_) => {}, _ => unimplemented!(),