diff options
author | Christian Poveda Ruiz <31802960+pvdrz@users.noreply.github.com> | 2022-11-22 11:41:32 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-22 11:41:32 -0500 |
commit | 046d6f9eea1803253c06dd99a0d38f5dcb5ed9c1 (patch) | |
tree | 286eeb0d0a9b7c7f2b756e96b01a21253158dc64 /bindgen/codegen | |
parent | f160d11d56007fe1b1125d04f0cb31af0b18fc6e (diff) |
Add `--wrap-unsafe-ops` option (#2354)
This reverts commit e8ffb42ab66405ac56d04494a30e54b584f2d4dd and adds a new `--wrap-unsafe-ops` option as a workaround.
Diffstat (limited to 'bindgen/codegen')
-rw-r--r-- | bindgen/codegen/dyngen.rs | 38 | ||||
-rw-r--r-- | bindgen/codegen/mod.rs | 64 |
2 files changed, 58 insertions, 44 deletions
diff --git a/bindgen/codegen/dyngen.rs b/bindgen/codegen/dyngen.rs index f310f14e..5e734ccd 100644 --- a/bindgen/codegen/dyngen.rs +++ b/bindgen/codegen/dyngen.rs @@ -1,4 +1,5 @@ use crate::codegen; +use crate::ir::context::BindgenContext; use crate::ir::function::ClangAbi; use proc_macro2::Ident; @@ -72,12 +73,22 @@ impl DynamicItems { Self::default() } - pub fn get_tokens(&self, lib_ident: Ident) -> proc_macro2::TokenStream { + pub fn get_tokens( + &self, + lib_ident: Ident, + ctx: &BindgenContext, + ) -> proc_macro2::TokenStream { let struct_members = &self.struct_members; let constructor_inits = &self.constructor_inits; let init_fields = &self.init_fields; let struct_implementation = &self.struct_implementation; + let from_library = if ctx.options().wrap_unsafe_ops { + quote!(unsafe { Self::from_library(library) }) + } else { + quote!(Self::from_library(library)) + }; + quote! { extern crate libloading; @@ -92,9 +103,7 @@ impl DynamicItems { ) -> Result<Self, ::libloading::Error> where P: AsRef<::std::ffi::OsStr> { let library = ::libloading::Library::new(path)?; - unsafe { - Self::from_library(library) - } + #from_library } pub unsafe fn from_library<L>( @@ -126,6 +135,7 @@ impl DynamicItems { ret: proc_macro2::TokenStream, ret_ty: proc_macro2::TokenStream, attributes: Vec<proc_macro2::TokenStream>, + ctx: &BindgenContext, ) { if !is_variadic { assert_eq!(args.len(), args_identifiers.len()); @@ -149,8 +159,10 @@ impl DynamicItems { } else { quote! { self.#ident.as_ref().expect("Expected function, got error.") } }; - let call_body = quote! { - (#fn_)(#( #args_identifiers ),*) + let call_body = if ctx.options().wrap_unsafe_ops { + quote!(unsafe { (#fn_)(#( #args_identifiers ),*) }) + } else { + quote!((#fn_)(#( #args_identifiers ),*) ) }; // We can't implement variadic functions from C easily, so we allow to @@ -159,22 +171,26 @@ impl DynamicItems { self.struct_implementation.push(quote! { #(#attributes)* pub unsafe fn #ident ( &self, #( #args ),* ) -> #ret_ty { - unsafe { - #call_body - } + #call_body } }); } // N.B: Unwrap the signature upon construction if it is required to be resolved. let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string()); + let library_get = if ctx.options().wrap_unsafe_ops { + quote!(unsafe { __library.get(#ident_str) }) + } else { + quote!(__library.get(#ident_str)) + }; + self.constructor_inits.push(if is_required { quote! { - let #ident = unsafe { __library.get(#ident_str) }.map(|sym| *sym)?; + let #ident = #library_get.map(|sym| *sym)?; } } else { quote! { - let #ident = unsafe { __library.get(#ident_str) }.map(|sym| *sym); + let #ident = #library_get.map(|sym| *sym); } }); diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index c1e92b77..e5372427 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -2585,9 +2585,7 @@ impl MethodCodegen for Method { }) } - let block = quote! { - #( #stmts );* - }; + let block = ctx.wrap_unsafe_ops(quote! ( #( #stmts );*)); let mut attrs = vec![attributes::inline()]; @@ -2601,9 +2599,7 @@ impl MethodCodegen for Method { methods.push(quote! { #(#attrs)* pub unsafe fn #name ( #( #args ),* ) #ret { - unsafe { - #block - } + #block } }); } @@ -4169,6 +4165,7 @@ impl CodeGenerator for Function { ret, ret_ty, attributes, + ctx, ); } else { result.push(tokens); @@ -4212,17 +4209,18 @@ fn objc_method_codegen( let methods_and_args = method.format_method_call(&fn_args); - let body = if method.is_class_method() { - let class_name = ctx.rust_ident( - class_name.expect("Generating a class method without class name?"), - ); - quote! { - msg_send!(class!(#class_name), #methods_and_args) - } - } else { - quote! { - msg_send!(*self, #methods_and_args) - } + let body = { + let body = if method.is_class_method() { + let class_name = ctx.rust_ident( + class_name + .expect("Generating a class method without class name?"), + ); + quote!(msg_send!(class!(#class_name), #methods_and_args)) + } else { + quote!(msg_send!(*self, #methods_and_args)) + }; + + ctx.wrap_unsafe_ops(body) }; let method_name = @@ -4230,9 +4228,7 @@ fn objc_method_codegen( methods.push(quote! { unsafe fn #method_name #sig where <Self as std::ops::Deref>::Target: objc::Message + Sized { - unsafe { - #body - } + #body } }); } @@ -4495,7 +4491,7 @@ pub(crate) fn codegen( if let Some(ref lib_name) = context.options().dynamic_library_name { let lib_ident = context.rust_ident(lib_name); let dynamic_items_tokens = - result.dynamic_items().get_tokens(lib_ident); + result.dynamic_items().get_tokens(lib_ident, context); result.push(dynamic_items_tokens); } @@ -4598,6 +4594,9 @@ pub mod utils { pub struct __BindgenUnionField<T>(::#prefix::marker::PhantomData<T>); }; + let transmute = + ctx.wrap_unsafe_ops(quote!(::#prefix::mem::transmute(self))); + let union_field_impl = quote! { impl<T> __BindgenUnionField<T> { #[inline] @@ -4607,16 +4606,12 @@ pub mod utils { #[inline] pub unsafe fn as_ref(&self) -> &T { - unsafe { - ::#prefix::mem::transmute(self) - } + #transmute } #[inline] pub unsafe fn as_mut(&mut self) -> &mut T { - unsafe { - ::#prefix::mem::transmute(self) - } + #transmute } } }; @@ -4711,6 +4706,13 @@ pub mod utils { ::#prefix::marker::PhantomData<T>, [T; 0]); }; + let from_raw_parts = ctx.wrap_unsafe_ops(quote! ( + ::#prefix::slice::from_raw_parts(self.as_ptr(), len) + )); + let from_raw_parts_mut = ctx.wrap_unsafe_ops(quote! ( + ::#prefix::slice::from_raw_parts_mut(self.as_mut_ptr(), len) + )); + let incomplete_array_impl = quote! { impl<T> __IncompleteArrayField<T> { #[inline] @@ -4730,16 +4732,12 @@ pub mod utils { #[inline] pub unsafe fn as_slice(&self, len: usize) -> &[T] { - unsafe { - ::#prefix::slice::from_raw_parts(self.as_ptr(), len) - } + #from_raw_parts } #[inline] pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { - unsafe { - ::#prefix::slice::from_raw_parts_mut(self.as_mut_ptr(), len) - } + #from_raw_parts_mut } } }; |