From 1a86473ddf6203cd817ac3ca4682f43575997565 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Wed, 14 Feb 2024 15:06:48 +0100 Subject: [PATCH] Fix type usage to use the real C types wherever applicable --- rustler/src/codegen_runtime.rs | 4 ++-- rustler/src/export.rs | 6 ++--- rustler/src/nif.rs | 8 +++---- rustler/src/wrapper.rs | 2 +- rustler/src/wrapper/atom.rs | 6 ++--- rustler/src/wrapper/resource.rs | 5 ++-- rustler_codegen/src/init.rs | 4 ++-- rustler_codegen/src/nif.rs | 14 +++++++---- rustler_sys/build.rs | 24 +++++++++---------- rustler_sys/src/rustler_sys_api.rs | 10 ++++---- rustler_tests/lib/rustler_test.ex | 2 +- .../native/rustler_test/src/test_nif_attrs.rs | 2 +- rustler_tests/test/nif_attrs_test.exs | 2 +- 13 files changed, 47 insertions(+), 42 deletions(-) diff --git a/rustler/src/codegen_runtime.rs b/rustler/src/codegen_runtime.rs index deffed54..d6b97a33 100644 --- a/rustler/src/codegen_runtime.rs +++ b/rustler/src/codegen_runtime.rs @@ -8,7 +8,7 @@ use crate::{Encoder, Env, OwnedBinary, Term}; // Names used by the `rustler::init!` macro or other generated code. pub use crate::wrapper::exception::raise_exception; pub use crate::wrapper::{ - c_int, c_void, get_nif_resource_type_init_size, DEF_NIF_ENTRY, DEF_NIF_FUNC, + c_char, c_int, c_uint, c_void, get_nif_resource_type_init_size, DEF_NIF_ENTRY, DEF_NIF_FUNC, MUTABLE_NIF_RESOURCE_HANDLE, NIF_ENV, NIF_MAJOR_VERSION, NIF_MINOR_VERSION, NIF_TERM, }; @@ -73,7 +73,7 @@ impl NifReturned { args, } => rustler_sys::enif_schedule_nif( env.as_c_arg(), - fun_name.as_ptr() as *const u8, + fun_name.as_ptr() as *const c_char, flags as i32, fun, args.len() as i32, diff --git a/rustler/src/export.rs b/rustler/src/export.rs index 8d293a1d..48aa2648 100644 --- a/rustler/src/export.rs +++ b/rustler/src/export.rs @@ -44,14 +44,14 @@ macro_rules! rustler_export_nifs { let entry = $crate::codegen_runtime::DEF_NIF_ENTRY { major: $crate::codegen_runtime::NIF_MAJOR_VERSION, minor: $crate::codegen_runtime::NIF_MINOR_VERSION, - name: concat!($name, "\x00") as *const str as *const u8, + name: concat!($name, "\x00") as *const str as *const $crate::codegen_runtime::c_char, num_of_funcs: FUN_ENTRIES.len() as $crate::codegen_runtime::c_int, funcs: FUN_ENTRIES.as_ptr(), load: Some(nif_load), reload: None, upgrade: None, unload: None, - vm_variant: b"beam.vanilla\x00".as_ptr(), + vm_variant: b"beam.vanilla\x00".as_ptr() as *const $crate::codegen_runtime::c_char, options: 0, sizeof_ErlNifResourceTypeInit: $crate::codegen_runtime::get_nif_resource_type_init_size(), }; @@ -66,7 +66,7 @@ macro_rules! rustler_export_nifs { }; (internal_item_init, ($nif_name:expr, $nif_arity:expr, $nif_fun:path, $nif_flag:expr)) => { $crate::codegen_runtime::DEF_NIF_FUNC { - name: concat!($nif_name, "\x00") as *const str as *const u8, + name: concat!($nif_name, "\x00") as *const str as *const $crate::codegen_runtime::c_char, arity: $nif_arity, function: { extern "C" fn nif_func( diff --git a/rustler/src/nif.rs b/rustler/src/nif.rs index 3d9342fa..7ee07ede 100644 --- a/rustler/src/nif.rs +++ b/rustler/src/nif.rs @@ -1,9 +1,9 @@ -use crate::codegen_runtime::{c_int, DEF_NIF_FUNC, NIF_ENV, NIF_TERM}; +use crate::codegen_runtime::{c_char, c_int, c_uint, DEF_NIF_FUNC, NIF_ENV, NIF_TERM}; pub trait Nif { - const NAME: *const u8; - const ARITY: u32; - const FLAGS: u32; + const NAME: *const c_char; + const ARITY: c_uint; + const FLAGS: c_uint; const FUNC: DEF_NIF_FUNC; const RAW_FUNC: unsafe extern "C" fn( nif_env: NIF_ENV, diff --git a/rustler/src/wrapper.rs b/rustler/src/wrapper.rs index 904c017f..4efac11d 100644 --- a/rustler/src/wrapper.rs +++ b/rustler/src/wrapper.rs @@ -26,7 +26,7 @@ pub use rustler_sys::{ ERL_NIF_THR_DIRTY_IO_SCHEDULER, ERL_NIF_THR_NORMAL_SCHEDULER, ERL_NIF_THR_UNDEFINED, }; -pub use std::os::raw::{c_double, c_int, c_uchar, c_uint, c_void}; +pub use rustler_sys::{c_char, c_double, c_int, c_uchar, c_uint, c_void}; pub type size_t = usize; pub type NIF_ENV = *mut rustler_sys::ErlNifEnv; diff --git a/rustler/src/wrapper/atom.rs b/rustler/src/wrapper/atom.rs index 0c9134c7..919afa3c 100644 --- a/rustler/src/wrapper/atom.rs +++ b/rustler/src/wrapper/atom.rs @@ -1,16 +1,16 @@ -use crate::wrapper::{c_uint, NIF_ENV, NIF_TERM}; +use crate::wrapper::{c_char, c_uint, NIF_ENV, NIF_TERM}; use crate::Error; use rustler_sys::ErlNifCharEncoding::ERL_NIF_LATIN1; pub unsafe fn make_atom(env: NIF_ENV, name: &[u8]) -> NIF_TERM { - rustler_sys::enif_make_atom_len(env, name.as_ptr(), name.len()) + rustler_sys::enif_make_atom_len(env, name.as_ptr() as *const c_char, name.len()) } pub unsafe fn make_existing_atom(env: NIF_ENV, name: &[u8]) -> Option { let mut atom_out: NIF_TERM = 0; let success = rustler_sys::enif_make_existing_atom_len( env, - name.as_ptr(), + name.as_ptr() as *const c_char, name.len(), &mut atom_out as *mut NIF_TERM, ERL_NIF_LATIN1, diff --git a/rustler/src/wrapper/resource.rs b/rustler/src/wrapper/resource.rs index 33dc6c43..8b9cdad4 100644 --- a/rustler/src/wrapper/resource.rs +++ b/rustler/src/wrapper/resource.rs @@ -2,6 +2,7 @@ use crate::wrapper::{ NifResourceDtor, NifResourceFlags, NIF_ENV, NIF_RESOURCE_HANDLE, NIF_RESOURCE_TYPE, NIF_TERM, }; +use rustler_sys::c_char; pub use rustler_sys::{ enif_alloc_resource as alloc_resource, enif_keep_resource as keep_resource, enif_make_resource as make_resource, enif_release_resource as release_resource, @@ -20,8 +21,8 @@ pub unsafe fn open_resource_type( assert_eq!(name.last().cloned(), Some(0u8)); // Currently unused as per erlang nif documentation - let module_p: *const u8 = ptr::null(); - let name_p = name.as_ptr(); + let module_p: *const c_char = ptr::null(); + let name_p = name.as_ptr() as *const c_char; let res = { let mut tried = MaybeUninit::uninit(); rustler_sys::enif_open_resource_type(env, module_p, name_p, dtor, flags, tried.as_mut_ptr()) diff --git a/rustler_codegen/src/init.rs b/rustler_codegen/src/init.rs index 6090fdf5..ee892a4f 100644 --- a/rustler_codegen/src/init.rs +++ b/rustler_codegen/src/init.rs @@ -66,7 +66,7 @@ impl From for proc_macro2::TokenStream { let entry = rustler::codegen_runtime::DEF_NIF_ENTRY { major: rustler::codegen_runtime::NIF_MAJOR_VERSION, minor: rustler::codegen_runtime::NIF_MINOR_VERSION, - name: concat!(#name, "\0").as_ptr() as *const u8, + name: concat!(#name, "\0").as_ptr() as *const rustler::codegen_runtime::c_char, num_of_funcs: #num_of_funcs as rustler::codegen_runtime::c_int, funcs: [#funcs].as_ptr(), load: { @@ -85,7 +85,7 @@ impl From for proc_macro2::TokenStream { reload: None, upgrade: None, unload: None, - vm_variant: b"beam.vanilla\0".as_ptr(), + vm_variant: b"beam.vanilla\0".as_ptr() as *const rustler::codegen_runtime::c_char, options: 0, sizeof_ErlNifResourceTypeInit: rustler::codegen_runtime::get_nif_resource_type_init_size(), }; diff --git a/rustler_codegen/src/nif.rs b/rustler_codegen/src/nif.rs index 713a92aa..f7d65256 100644 --- a/rustler_codegen/src/nif.rs +++ b/rustler_codegen/src/nif.rs @@ -48,17 +48,21 @@ pub fn transcoder_decorator(nif_attributes: NifAttributes, fun: syn::ItemFn) -> let argument_names = create_function_params(inputs.clone()); let erl_func_name = nif_attributes .custom_name - .map(|n| syn::Ident::new(n.value().as_str(), Span::call_site())) - .unwrap_or_else(|| name.clone()); + .map(|n| n.value().to_string()) + .unwrap_or_else(|| name.clone().to_string()); + + if !erl_func_name.is_ascii() { + panic!("Only ASCII strings are supported as function names"); + } quote! { #[allow(non_camel_case_types)] pub struct #name; impl rustler::Nif for #name { - const NAME: *const u8 = concat!(stringify!(#erl_func_name), "\0").as_ptr() as *const u8; - const ARITY: u32 = #arity; - const FLAGS: u32 = #flags as u32; + const NAME: *const rustler::codegen_runtime::c_char = concat!(#erl_func_name, "\0").as_ptr() as *const rustler::codegen_runtime::c_char; + const ARITY: rustler::codegen_runtime::c_uint = #arity; + const FLAGS: rustler::codegen_runtime::c_uint = #flags as rustler::codegen_runtime::c_uint; const RAW_FUNC: unsafe extern "C" fn( nif_env: rustler::codegen_runtime::NIF_ENV, argc: rustler::codegen_runtime::c_int, diff --git a/rustler_sys/build.rs b/rustler_sys/build.rs index 70bdfe81..090fb5c8 100644 --- a/rustler_sys/build.rs +++ b/rustler_sys/build.rs @@ -515,7 +515,7 @@ fn build_api(b: &mut dyn ApiBuilder, opts: &GenerateOptions) { "enif_is_empty_list", "arg1: *mut ErlNifEnv, term: ERL_NIF_TERM", ); - b.func("*const ErlNifResourceType", "enif_open_resource_type", "arg1: *mut ErlNifEnv, module_str: *const c_uchar, name_str: *const c_uchar, dtor: Option, flags: ErlNifResourceFlags, tried: *mut ErlNifResourceFlags"); + b.func("*const ErlNifResourceType", "enif_open_resource_type", "arg1: *mut ErlNifEnv, module_str: *const c_char, name_str: *const c_char, dtor: Option, flags: ErlNifResourceFlags, tried: *mut ErlNifResourceFlags"); b.func( "*mut c_void", "enif_alloc_resource", @@ -557,13 +557,13 @@ fn build_api(b: &mut dyn ApiBuilder, opts: &GenerateOptions) { b.func( "ERL_NIF_TERM", "enif_make_atom_len", - "env: *mut ErlNifEnv, name: *const c_uchar, len: size_t", + "env: *mut ErlNifEnv, name: *const c_char, len: size_t", ); - b.func("c_int", "enif_make_existing_atom_len", "env: *mut ErlNifEnv, name: *const c_uchar, len: size_t, atom: *mut ERL_NIF_TERM, arg1: ErlNifCharEncoding"); + b.func("c_int", "enif_make_existing_atom_len", "env: *mut ErlNifEnv, name: *const c_char, len: size_t, atom: *mut ERL_NIF_TERM, arg1: ErlNifCharEncoding"); b.func( "ERL_NIF_TERM", "enif_make_string_len", - "env: *mut ErlNifEnv, string: *const c_uchar, len: size_t, arg1: ErlNifCharEncoding", + "env: *mut ErlNifEnv, string: *const c_char, len: size_t, arg1: ErlNifCharEncoding", ); b.func("*mut ErlNifEnv", "enif_alloc_env", ""); b.func("", "enif_free_env", "env: *mut ErlNifEnv"); @@ -633,8 +633,8 @@ fn build_api(b: &mut dyn ApiBuilder, opts: &GenerateOptions) { "enif_is_number", "arg1: *mut ErlNifEnv, term: ERL_NIF_TERM", ); - b.func("*mut c_void", "enif_dlopen", "lib: *const c_uchar, err_handler: Option, err_arg: *mut c_void"); - b.func("*mut c_void", "enif_dlsym", "handle: *mut c_void, symbol: *const c_uchar, err_handler: Option, err_arg: *mut c_void"); + b.func("*mut c_void", "enif_dlopen", "lib: *const c_char, err_handler: Option, err_arg: *mut c_void"); + b.func("*mut c_void", "enif_dlsym", "handle: *mut c_void, symbol: *const c_char, err_handler: Option, err_arg: *mut c_void"); b.func( "c_int", "enif_consume_timeslice", @@ -690,7 +690,7 @@ fn build_api(b: &mut dyn ApiBuilder, opts: &GenerateOptions) { "env: *mut ErlNifEnv, iter: *mut ErlNifMapIterator", ); b.func("c_int", "enif_map_iterator_get_pair", "env: *mut ErlNifEnv, iter: *mut ErlNifMapIterator, key: *mut ERL_NIF_TERM, value: *mut ERL_NIF_TERM"); - b.func("ERL_NIF_TERM", "enif_schedule_nif", "env: *mut ErlNifEnv, fun_name: *const c_uchar, flags:c_int, fp: unsafe extern \"C\" fn(env: *mut ErlNifEnv, argc:c_int, argv:*const ERL_NIF_TERM) -> ERL_NIF_TERM, argc:c_int, argv:*const ERL_NIF_TERM"); + b.func("ERL_NIF_TERM", "enif_schedule_nif", "env: *mut ErlNifEnv, fun_name: *const c_char, flags:c_int, fp: unsafe extern \"C\" fn(env: *mut ErlNifEnv, argc:c_int, argv:*const ERL_NIF_TERM) -> ERL_NIF_TERM, argc:c_int, argv:*const ERL_NIF_TERM"); // exception b.func( @@ -708,7 +708,7 @@ fn build_api(b: &mut dyn ApiBuilder, opts: &GenerateOptions) { b.func( "c_int", "enif_getenv", - "key: *const c_uchar, value: *mut c_uchar, value_size: *mut size_t", + "key: *const c_char, value: *mut c_char, value_size: *mut size_t", ); // time @@ -766,7 +766,7 @@ fn build_api(b: &mut dyn ApiBuilder, opts: &GenerateOptions) { if opts.nif_version >= (2, 12) { b.func("c_int", "enif_select", "env: *mut ErlNifEnv, e: ErlNifEvent, flags: ErlNifSelectFlags, obj: *const c_void, pid: *const ErlNifPid, eref: ERL_NIF_TERM"); - b.func("*const ErlNifResourceType", "enif_open_resource_type_x", "env: *mut ErlNifEnv, name_str: *const c_uchar, init: *const ErlNifResourceTypeInit, flags: ErlNifResourceFlags, tried: *mut ErlNifResourceFlags"); + b.func("*const ErlNifResourceType", "enif_open_resource_type_x", "env: *mut ErlNifEnv, name_str: *const c_char, init: *const ErlNifResourceTypeInit, flags: ErlNifResourceFlags, tried: *mut ErlNifResourceFlags"); b.func("c_int", "enif_monitor_process", "env: *mut ErlNifEnv, obj: *const c_void, pid: *const ErlNifPid, monitor: *mut ErlNifMonitor"); b.func( "c_int", @@ -862,7 +862,7 @@ fn build_api(b: &mut dyn ApiBuilder, opts: &GenerateOptions) { // 2.16 was introduced in OTP 24 if opts.nif_version >= (2, 16) { - b.func("*const ErlNifResourceType", "enif_init_resource_type", "env: *mut ErlNifEnv, name_str: *const c_uchar, init: *const ErlNifResourceTypeInit, flags: ErlNifResourceFlags, tried: *mut ErlNifResourceFlags"); + b.func("*const ErlNifResourceType", "enif_init_resource_type", "env: *mut ErlNifEnv, name_str: *const c_char, init: *const ErlNifResourceTypeInit, flags: ErlNifResourceFlags, tried: *mut ErlNifResourceFlags"); b.func("c_int", "enif_dynamic_resource_call", "env: *mut ErlNifEnv, module: ERL_NIF_TERM, name: ERL_NIF_TERM, rsrc: ERL_NIF_TERM, call_data: *const c_void"); } @@ -874,8 +874,8 @@ fn build_api(b: &mut dyn ApiBuilder, opts: &GenerateOptions) { "env: *mut ErlNifEnv, opt: ErlNifOption", ); b.func("c_int", "enif_get_string_length", "env: *mut ErlNifEnv, list: ERL_NIF_TERM, len: *mut c_uint, encoding: ErlNifCharEncoding"); - b.func("c_int", "enif_make_new_atom", "env: *mut ErlNifEnv, name: *const c_uchar, atom: *mut ERL_NIF_TERM, encoding: ErlNifCharEncoding"); - b.func("c_int", "enif_make_new_atom_len", "env: *mut ErlNifEnv, name: *const c_uchar, len: size_t, atom: *mut ERL_NIF_TERM, encoding: ErlNifCharEncoding"); + b.func("c_int", "enif_make_new_atom", "env: *mut ErlNifEnv, name: *const c_char, atom: *mut ERL_NIF_TERM, encoding: ErlNifCharEncoding"); + b.func("c_int", "enif_make_new_atom_len", "env: *mut ErlNifEnv, name: *const c_char, len: size_t, atom: *mut ERL_NIF_TERM, encoding: ErlNifCharEncoding"); } } diff --git a/rustler_sys/src/rustler_sys_api.rs b/rustler_sys/src/rustler_sys_api.rs index ab15827b..4ba58089 100644 --- a/rustler_sys/src/rustler_sys_api.rs +++ b/rustler_sys/src/rustler_sys_api.rs @@ -4,7 +4,7 @@ #[cfg(windows)] use unreachable::UncheckedOptionExt; // unchecked unwrap used in generated Windows code -pub use std::os::raw::{c_char, c_double, c_int, c_long, c_uchar, c_uint, c_ulong, c_void}; +pub use std::ffi::{c_char, c_double, c_int, c_long, c_uchar, c_uint, c_ulong, c_void}; use std::os; @@ -41,7 +41,7 @@ unsafe impl Send for ErlNifEnv {} // #[allow(missing_copy_implementations)] #[repr(C)] pub struct ErlNifFunc { - pub name: *const u8, + pub name: *const c_char, pub arity: c_uint, pub function: unsafe extern "C" fn( env: *mut ErlNifEnv, @@ -59,7 +59,7 @@ pub struct ErlNifFunc { pub struct ErlNifEntry { pub major: c_int, pub minor: c_int, - pub name: *const u8, + pub name: *const c_char, pub num_of_funcs: c_int, pub funcs: *const ErlNifFunc, pub load: Option< @@ -85,7 +85,7 @@ pub struct ErlNifEntry { ) -> c_int, >, pub unload: Option ()>, - pub vm_variant: *const u8, + pub vm_variant: *const c_char, pub options: c_uint, // added in 2.7 pub sizeof_ErlNifResourceTypeInit: usize, // added in 2.12 } @@ -98,7 +98,7 @@ pub const ERL_NIF_DIRTY_NIF_OPTION: c_uint = 1; #[repr(C)] pub struct ErlNifBinary { pub size: size_t, - pub data: *mut u8, + pub data: *mut c_uchar, ref_bin: *mut c_void, _spare: [*mut c_void; 2], } diff --git a/rustler_tests/lib/rustler_test.ex b/rustler_tests/lib/rustler_test.ex index 1adaded7..ce424d40 100644 --- a/rustler_tests/lib/rustler_test.ex +++ b/rustler_tests/lib/rustler_test.ex @@ -121,7 +121,7 @@ defmodule RustlerTest do def raise_term_with_atom_error(), do: err() def term_with_tuple_error(), do: err() - def nif_attrs_can_rename(), do: err() + def nif_attrs_can_rename!(), do: err() def add_from_tuple(_tuple), do: err() def add_one_to_tuple(_tuple), do: err() diff --git a/rustler_tests/native/rustler_test/src/test_nif_attrs.rs b/rustler_tests/native/rustler_test/src/test_nif_attrs.rs index 1c40c22c..e992d0b8 100644 --- a/rustler_tests/native/rustler_test/src/test_nif_attrs.rs +++ b/rustler_tests/native/rustler_test/src/test_nif_attrs.rs @@ -1,4 +1,4 @@ -#[rustler::nif(name = "nif_attrs_can_rename")] +#[rustler::nif(name = "nif_attrs_can_rename!")] pub fn can_rename() -> bool { true } diff --git a/rustler_tests/test/nif_attrs_test.exs b/rustler_tests/test/nif_attrs_test.exs index 1e916c91..6805436e 100644 --- a/rustler_tests/test/nif_attrs_test.exs +++ b/rustler_tests/test/nif_attrs_test.exs @@ -2,6 +2,6 @@ defmodule NifAttrsTest do use ExUnit.Case test "can rename a NIF with an attribute" do - assert RustlerTest.nif_attrs_can_rename() + assert RustlerTest.nif_attrs_can_rename!() end end