Skip to content

Commit f845501

Browse files
committed
Make independent of rustler itself and fix Windows
1 parent 9d902e9 commit f845501

File tree

4 files changed

+92
-6
lines changed

4 files changed

+92
-6
lines changed

cargo-rustler/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,4 @@ metadata = { msrv = "1.77" }
1010
cargo_metadata = "0.19.2"
1111
clap = { version = "4.5", features = [ "derive" ] }
1212
libloading = "0.8"
13-
rustler = { version = "0.36.1", path = "../rustler" }
1413
tempfile = "3.19.1"

cargo-rustler/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod fake_symbols;
44
mod nif;
55
mod nif_elixir;
66
mod nif_erlang;
7+
mod nif_types;
78
mod rust_build;
89

910
use std::path::PathBuf;

cargo-rustler/src/nif.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
use crate::nif_types::ErlNifEntry;
12
use libloading::{Library, Symbol};
2-
use rustler::sys::ErlNifEntry;
33
use std::ffi::CStr;
44
use std::path::{Path, PathBuf};
55

@@ -28,12 +28,18 @@ unsafe fn maybe_call_nif_init(
2828
unsafe fn maybe_call_nif_init(
2929
lib: &Library,
3030
) -> Result<*const ErlNifEntry, Box<dyn std::error::Error>> {
31-
use rustler_sys::TWinDynNifCallbacks;
32-
static NULL_CALLBACKS: TWinDynNifCallbacks = TWinDynNifCallbacks {};
33-
let func: Symbol<unsafe extern "C" fn(*mut TWinDynNifCallbacks) -> *const ErlNifEntry> =
31+
static mut NULL_CALLBACKS: [usize; 1024] = [0; 1024];
32+
// enif_priv_data
33+
NULL_CALLBACKS[0] = 0;
34+
// enif_alloc
35+
NULL_CALLBACKS[1] = crate::fake_symbols::enif_alloc as *mut c_void as usize;
36+
// enif_free
37+
NULL_CALLBACKS[2] = crate::fake_symbols::enif_free as *mut c_void as usize;
38+
39+
let func: Symbol<unsafe extern "C" fn(*mut [usize; 1024]) -> *const ErlNifEntry> =
3440
lib.get(b"nif_init")?;
3541

36-
func(&NULL_CALLBACKS)
42+
Ok(func(std::ptr::addr_of_mut!(NULL_CALLBACKS)))
3743
}
3844

3945
impl NifLibrary {

cargo-rustler/src/nif_types.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#![allow(clippy::missing_safety_doc)]
2+
#![allow(clippy::upper_case_acronyms)]
3+
4+
pub use std::ffi::{c_char, c_int, c_uint, c_void};
5+
6+
#[allow(non_camel_case_types)]
7+
pub type size_t = usize;
8+
9+
#[allow(non_camel_case_types)]
10+
pub type ERL_NIF_UINT = size_t;
11+
12+
#[allow(non_camel_case_types)]
13+
pub type ERL_NIF_TERM = ERL_NIF_UINT;
14+
15+
/// See [ErlNifEnv](http://www.erlang.org/doc/man/erl_nif.html#ErlNifEnv) in the Erlang docs.
16+
#[derive(Debug)]
17+
#[allow(missing_copy_implementations)]
18+
#[repr(C)]
19+
pub struct ErlNifEnv {
20+
dummy: *mut c_void, // block automatic Send and Sync traits. Ref https://doc.rust-lang.org/beta/nomicon/send-and-sync.html
21+
}
22+
23+
// Ownership of an env may be safely transfers between threads, therefore ErlNifEnv is Send.
24+
// This is the common use case for process independent environments created with enif_alloc_env().
25+
// ErlNifEnv is NOT Sync because it is thread unsafe.
26+
unsafe impl Send for ErlNifEnv {}
27+
28+
/// See [ErlNifFunc](http://www.erlang.org/doc/man/erl_nif.html#ErlNifFunc) in the Erlang docs.
29+
// #[allow(missing_copy_implementations)]
30+
#[derive(Debug)]
31+
#[repr(C)]
32+
pub struct ErlNifFunc {
33+
pub name: *const c_char,
34+
pub arity: c_uint,
35+
pub function: unsafe extern "C" fn(
36+
env: *mut ErlNifEnv,
37+
argc: c_int,
38+
argv: *const ERL_NIF_TERM,
39+
) -> ERL_NIF_TERM,
40+
pub flags: c_uint,
41+
}
42+
43+
// #[allow(missing_copy_implementations)]
44+
#[doc(hidden)]
45+
#[derive(Debug)]
46+
#[repr(C)]
47+
#[allow(non_snake_case)]
48+
pub struct ErlNifEntry {
49+
pub major: c_int,
50+
pub minor: c_int,
51+
pub name: *const c_char,
52+
pub num_of_funcs: c_int,
53+
pub funcs: *const ErlNifFunc,
54+
pub load: Option<
55+
unsafe extern "C" fn(
56+
env: *mut ErlNifEnv,
57+
priv_data: *mut *mut c_void,
58+
load_info: ERL_NIF_TERM,
59+
) -> c_int,
60+
>,
61+
pub reload: Option<
62+
unsafe extern "C" fn(
63+
env: *mut ErlNifEnv,
64+
priv_data: *mut *mut c_void,
65+
load_info: ERL_NIF_TERM,
66+
) -> c_int,
67+
>,
68+
pub upgrade: Option<
69+
unsafe extern "C" fn(
70+
env: *mut ErlNifEnv,
71+
priv_data: *mut *mut c_void,
72+
old_priv_data: *mut *mut c_void,
73+
load_info: ERL_NIF_TERM,
74+
) -> c_int,
75+
>,
76+
pub unload: Option<unsafe extern "C" fn(env: *mut ErlNifEnv, priv_data: *mut c_void) -> ()>,
77+
pub vm_variant: *const c_char,
78+
pub options: c_uint, // added in 2.7
79+
pub sizeof_ErlNifResourceTypeInit: usize, // added in 2.12
80+
}

0 commit comments

Comments
 (0)