X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=c-bindings-gen%2Fsrc%2Fmain.rs;h=6853534624427a7b0a5fcb8295f8b4999254e672;hb=ed96ce032ac607694f7716a73c28a75eb056953a;hp=28cce19e9715067a150a194f496b7e27eb03e640;hpb=4f282d4cdae9b2e79e4fd604b629517898f02262;p=ldk-c-bindings diff --git a/c-bindings-gen/src/main.rs b/c-bindings-gen/src/main.rs index 28cce19..6853534 100644 --- a/c-bindings-gen/src/main.rs +++ b/c-bindings-gen/src/main.rs @@ -36,6 +36,7 @@ use blocks::*; const DEFAULT_IMPORTS: &'static str = " use alloc::str::FromStr; +use alloc::string::String; use core::ffi::c_void; use core::convert::Infallible; use bitcoin::hashes::Hash; @@ -73,7 +74,7 @@ fn maybe_convert_trait_impl(w: &mut W, trait_path: &syn::Path let mut for_obj_vec = Vec::new(); types.write_c_type(&mut for_obj_vec, for_ty, Some(generics), false); full_obj_path = String::from_utf8(for_obj_vec).unwrap(); - assert!(full_obj_path.starts_with(TypeResolver::generated_container_path())); + if !full_obj_path.starts_with(TypeResolver::generated_container_path()) { return; } for_obj = full_obj_path[TypeResolver::generated_container_path().len() + 2..].into(); } @@ -94,7 +95,6 @@ fn maybe_convert_trait_impl(w: &mut W, trait_path: &syn::Path writeln!(w, "}}").unwrap(); if has_inner { - writeln!(w, "#[no_mangle]").unwrap(); writeln!(w, "pub(crate) extern \"C\" fn {}_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z {{", for_obj).unwrap(); writeln!(w, "\tcrate::c_types::serialize_obj(unsafe {{ &*(obj as *const native{}) }})", for_obj).unwrap(); writeln!(w, "}}").unwrap(); @@ -266,8 +266,8 @@ macro_rules! walk_supertraits { ($t: expr, $types: expr, ($( $($pat: pat)|* => $ } } } macro_rules! get_module_type_resolver { - ($module: expr, $crate_libs: expr, $crate_types: expr) => { { - let module: &str = &$module; + ($type_in_module: expr, $crate_types: expr) => { { + let module: &str = &$type_in_module; let mut module_iter = module.rsplitn(2, "::"); module_iter.next().unwrap(); let module = module_iter.next().unwrap(); @@ -303,7 +303,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty (s, _i, _) => { if let Some(supertrait) = types.crate_types.traits.get(s) { supertrait_name = s.to_string(); - supertrait_resolver = get_module_type_resolver!(supertrait_name, types.crate_libs, types.crate_types); + supertrait_resolver = get_module_type_resolver!(supertrait_name, types.crate_types); gen_types.learn_associated_types(&supertrait, &supertrait_resolver); break; } @@ -533,8 +533,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty writeln!(w, "\ttype {} = crate::{};", t.ident, $type_resolver.resolve_path(&tr.path, Some(&gen_types))).unwrap(); for bound in bounds_iter { if let syn::TypeParamBound::Trait(t) = bound { - // We only allow for `?Sized` here. - if let syn::TraitBoundModifier::Maybe(_) = t.modifier {} else { panic!(); } + // We only allow for `Sized` here. assert_eq!(t.path.segments.len(), 1); assert_eq!(format!("{}", t.path.segments[0].ident), "Sized"); } @@ -554,8 +553,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty writeln!(w, "unsafe impl Send for {} {{}}", trait_name).unwrap(); writeln!(w, "unsafe impl Sync for {} {{}}", trait_name).unwrap(); - writeln!(w, "#[no_mangle]").unwrap(); - writeln!(w, "pub(crate) extern \"C\" fn {}_clone_fields(orig: &{}) -> {} {{", trait_name, trait_name, trait_name).unwrap(); + writeln!(w, "pub(crate) fn {}_clone_fields(orig: &{}) -> {} {{", trait_name, trait_name, trait_name).unwrap(); writeln!(w, "\t{} {{", trait_name).unwrap(); writeln!(w, "\t\tthis_arg: orig.this_arg,").unwrap(); for (field, clone_fn, _) in generated_fields.iter() { @@ -601,10 +599,10 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty }, (s, i, generic_args) => { if let Some(supertrait) = types.crate_types.traits.get(s) { - let resolver = get_module_type_resolver!(s, types.crate_libs, types.crate_types); + let resolver = get_module_type_resolver!(s, types.crate_types); macro_rules! impl_supertrait { ($s: expr, $supertrait: expr, $i: expr, $generic_args: expr) => { - let resolver = get_module_type_resolver!($s, types.crate_libs, types.crate_types); + let resolver = get_module_type_resolver!($s, types.crate_types); // Blindly assume that the same imports where `supertrait` is defined are also // imported here. This will almost certainly break at some point, but it should be @@ -647,6 +645,8 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty writeln!(w, "// directly as a Deref trait in higher-level structs:").unwrap(); writeln!(w, "impl core::ops::Deref for {} {{\n\ttype Target = Self;", trait_name).unwrap(); writeln!(w, "\tfn deref(&self) -> &Self {{\n\t\tself\n\t}}\n}}").unwrap(); + writeln!(w, "impl core::ops::DerefMut for {} {{", trait_name).unwrap(); + writeln!(w, "\tfn deref_mut(&mut self) -> &mut Self {{\n\t\tself\n\t}}\n}}").unwrap(); } writeln!(w, "/// Calls the free function if one is set").unwrap(); @@ -805,12 +805,25 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct, define_field!(('a' as u8 + idx as u8) as char, ('0' as u8 + idx as u8) as char, field); } } - _ => unimplemented!() + syn::Fields::Unit => {}, } if all_fields_settable { // Build a constructor! writeln!(w, "/// Constructs a new {} given each field", struct_name).unwrap(); + match &s.fields { + syn::Fields::Named(fields) => { + writeln_arg_docs(w, &[], "", types, Some(&gen_types), + fields.named.iter().map(|field| (format!("{}_arg", field.ident.as_ref().unwrap()), &field.ty)), + None); + }, + syn::Fields::Unnamed(fields) => { + writeln_arg_docs(w, &[], "", types, Some(&gen_types), + fields.unnamed.iter().enumerate().map(|(idx, field)| (format!("{}_arg", ('a' as u8 + idx as u8)), &field.ty)), + None); + }, + syn::Fields::Unit => {}, + } write!(w, "#[must_use]\n#[no_mangle]\npub extern \"C\" fn {}_new(", struct_name).unwrap(); match &s.fields { @@ -828,7 +841,7 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct, types.write_c_type(w, &field.ty, Some(&gen_types), false); } } - _ => unreachable!() + syn::Fields::Unit => {}, } write!(w, ") -> {} {{\n\t", struct_name).unwrap(); match &s.fields { @@ -848,7 +861,7 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct, } } }, - _ => unreachable!() + syn::Fields::Unit => {}, } write!(w, "{} {{ inner: ObjOps::heap_alloc(", struct_name).unwrap(); match &s.fields { @@ -876,7 +889,7 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct, } write!(w, "\t)").unwrap(); }, - _ => unreachable!() + syn::Fields::Unit => write!(w, "{}::{} {{}}", types.module_path, struct_name).unwrap(), } writeln!(w, "), is_owned: true }}\n}}").unwrap(); } @@ -945,9 +958,11 @@ fn writeln_impl(w: &mut W, w_uses: &mut HashSet(w: &mut W, w_uses: &mut HashSet { if let Some(supertrait) = types.crate_types.traits.get(s) { supertrait_name = s.to_string(); - supertrait_resolver = get_module_type_resolver!(supertrait_name, types.crate_libs, types.crate_types); + supertrait_resolver = get_module_type_resolver!(supertrait_name, types.crate_types); gen_types.learn_associated_types(&supertrait, &supertrait_resolver); break; } @@ -966,7 +981,7 @@ fn writeln_impl(w: &mut W, w_uses: &mut HashSet(w: &mut W, w_uses: &mut HashSet { if let Some(supertrait_obj) = types.crate_types.traits.get(s) { @@ -1238,15 +1253,22 @@ fn writeln_impl(w: &mut W, w_uses: &mut HashSet { - if types.crate_types.traits.get(s).is_some() { - assert!(!types.is_clonable(s)); // We don't currently support cloning with a clonable supertrait - writeln!(w, "\tnew_obj.{}.this_arg = new_obj.this_arg;", t).unwrap(); - writeln!(w, "\tnew_obj.{}.free = None;", t).unwrap(); + + fn seek_supertraits(w: &mut W, pfx: &str, tr: &syn::ItemTrait, types: &TypeResolver) { + walk_supertraits!(tr, Some(types), ( + (s, t, _) => { + if types.crate_types.traits.get(s).is_some() { + assert!(!types.is_clonable(s)); // We don't currently support cloning with a clonable supertrait + writeln!(w, "\tnew_obj.{}{}.this_arg = new_obj.this_arg;", pfx, t).unwrap(); + writeln!(w, "\tnew_obj.{}{}.free = None;", pfx, t).unwrap(); + let tr = types.crate_types.traits.get(s).unwrap(); + let resolver = get_module_type_resolver!(s, types.crate_types); + seek_supertraits(w, &format!("{}.", t), tr, &resolver); + } } - } - ) ); + ) ); + } + seek_supertraits(w, "", trait_obj, types); writeln!(w, "}}").unwrap(); } write!(w, "\n").unwrap(); @@ -2200,9 +2222,13 @@ fn walk_private_mod<'a>(ast_storage: &'a FullLibraryAST, orig_crate: &str, modul if let Some(trait_path) = i.trait_.as_ref() { if let Some(tp) = import_resolver.maybe_resolve_path(&trait_path.1, None) { if let Some(sp) = import_resolver.maybe_resolve_path(&p.path, None) { - match crate_types.trait_impls.entry(sp) { - hash_map::Entry::Occupied(mut e) => { e.get_mut().push(tp); }, - hash_map::Entry::Vacant(e) => { e.insert(vec![tp]); }, + match crate_types.trait_impls.entry(sp.clone()) { + hash_map::Entry::Occupied(mut e) => { e.get_mut().push(tp.clone()); }, + hash_map::Entry::Vacant(e) => { e.insert(vec![tp.clone()]); }, + } + match crate_types.traits_impld.entry(tp) { + hash_map::Entry::Occupied(mut e) => { e.get_mut().push(sp); }, + hash_map::Entry::Vacant(e) => { e.insert(vec![sp]); }, } } } @@ -2312,9 +2338,13 @@ fn walk_ast_first_pass<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut Cr } if let Some(tp) = import_resolver.maybe_resolve_path(&trait_path.1, None) { if let Some(sp) = import_resolver.maybe_resolve_path(&p.path, None) { - match crate_types.trait_impls.entry(sp) { - hash_map::Entry::Occupied(mut e) => { e.get_mut().push(tp); }, - hash_map::Entry::Vacant(e) => { e.insert(vec![tp]); }, + match crate_types.trait_impls.entry(sp.clone()) { + hash_map::Entry::Occupied(mut e) => { e.get_mut().push(tp.clone()); }, + hash_map::Entry::Vacant(e) => { e.insert(vec![tp.clone()]); }, + } + match crate_types.traits_impld.entry(tp) { + hash_map::Entry::Occupied(mut e) => { e.get_mut().push(sp); }, + hash_map::Entry::Vacant(e) => { e.insert(vec![sp]); }, } } }