Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions rustler/src/codegen_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use std::ffi::CString;
use std::fmt;

use crate::sys::{enif_make_badarg, enif_raise_exception, enif_schedule_nif};
use crate::types::atom;
use crate::{Encoder, Env, OwnedBinary, Term};

Expand All @@ -13,13 +14,15 @@ pub use inventory;
pub use crate::resource::Registration as ResourceRegistration;

// Names used by the `rustler::init!` macro or other generated code.
pub use crate::wrapper::exception::raise_exception;
pub use crate::wrapper::{
c_char, c_int, c_uint, c_void, get_nif_resource_type_init_size, DEF_NIF_ENTRY, DEF_NIF_FUNC,
NIF_ENV, NIF_MAJOR_VERSION, NIF_MINOR_VERSION, NIF_TERM,
c_char, c_int, c_uint, c_void, get_nif_resource_type_init_size, NIF_MAJOR_VERSION,
NIF_MINOR_VERSION,
};

pub use crate::sys::{internal_set_symbols, internal_write_symbols, DynNifCallbacks};
pub use crate::sys::{
internal_set_symbols, internal_write_symbols, DynNifCallbacks, ErlNifEntry, ErlNifEnv,
ErlNifFunc, ErlNifTerm,
};

pub unsafe trait NifReturnable {
unsafe fn into_returned(self, env: Env) -> NifReturned;
Expand Down Expand Up @@ -59,31 +62,29 @@ unsafe impl NifReturnable for OwnedBinary {
}

pub enum NifReturned {
Term(NIF_TERM),
Raise(NIF_TERM),
Term(ErlNifTerm),
Raise(ErlNifTerm),
BadArg,
Reschedule {
fun_name: CString,
flags: crate::schedule::SchedulerFlags,
fun: unsafe extern "C" fn(NIF_ENV, i32, *const NIF_TERM) -> NIF_TERM,
args: Vec<NIF_TERM>,
fun: unsafe extern "C" fn(*mut ErlNifEnv, i32, *const ErlNifTerm) -> ErlNifTerm,
args: Vec<ErlNifTerm>,
},
}

impl NifReturned {
pub unsafe fn apply(self, env: Env) -> NIF_TERM {
pub unsafe fn apply(self, env: Env) -> ErlNifTerm {
match self {
NifReturned::Term(inner) => inner,
NifReturned::BadArg => crate::wrapper::exception::raise_badarg(env.as_c_arg()),
NifReturned::Raise(inner) => {
crate::wrapper::exception::raise_exception(env.as_c_arg(), inner)
}
NifReturned::BadArg => enif_make_badarg(env.as_c_arg()),
NifReturned::Raise(inner) => enif_raise_exception(env.as_c_arg(), inner),
NifReturned::Reschedule {
fun_name,
flags,
fun,
args,
} => crate::sys::enif_schedule_nif(
} => enif_schedule_nif(
env.as_c_arg(),
fun_name.as_ptr() as *const c_char,
flags as i32,
Expand Down
24 changes: 13 additions & 11 deletions rustler/src/env.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::sys::{enif_alloc_env, enif_clear_env, enif_free_env, enif_send, enif_whereis_pid};
use crate::sys::{
enif_alloc_env, enif_clear_env, enif_free_env, enif_send, enif_whereis_pid, ErlNifEnv,
ErlNifTerm,
};
use crate::thread::is_scheduler_thread;
use crate::types::LocalPid;
use crate::wrapper::{NIF_ENV, NIF_TERM};
use crate::{Encoder, Term};
use std::marker::PhantomData;
use std::ptr;
Expand All @@ -28,11 +30,11 @@ pub(crate) enum EnvKind {
#[derive(Clone, Copy)]
pub struct Env<'a> {
pub(crate) kind: EnvKind,
env: NIF_ENV,
env: *mut ErlNifEnv,
id: EnvId<'a>,
}

/// Two environments are equal if they're the same `NIF_ENV` value.
/// Two environments are equal if they're the same `*mut ErlNifEnv` pointer value.
///
/// A `Env<'a>` is equal to a `Env<'b>` if and only if `'a` and `'b` are the same lifetime.
impl<'b> PartialEq<Env<'b>> for Env<'_> {
Expand All @@ -51,7 +53,7 @@ impl<'a> Env<'a> {
#[inline]
pub(crate) unsafe fn new_internal<T>(
_lifetime_marker: &'a T,
env: NIF_ENV,
env: *mut ErlNifEnv,
kind: EnvKind,
) -> Env<'a> {
Env {
Expand All @@ -71,17 +73,17 @@ impl<'a> Env<'a> {
/// # Unsafe
/// Don't create multiple `Env`s with the same lifetime.
#[inline]
pub unsafe fn new<T>(_lifetime_marker: &'a T, env: NIF_ENV) -> Env<'a> {
pub unsafe fn new<T>(_lifetime_marker: &'a T, env: *mut ErlNifEnv) -> Env<'a> {
Self::new_internal(_lifetime_marker, env, EnvKind::ProcessBound)
}

#[doc(hidden)]
#[inline]
pub unsafe fn new_init_env<T>(_lifetime_marker: &'a T, env: NIF_ENV) -> Env<'a> {
pub unsafe fn new_init_env<T>(_lifetime_marker: &'a T, env: *mut ErlNifEnv) -> Env<'a> {
Self::new_internal(_lifetime_marker, env, EnvKind::Init)
}

pub fn as_c_arg(self) -> NIF_ENV {
pub fn as_c_arg(self) -> *mut ErlNifEnv {
self.env
}

Expand Down Expand Up @@ -202,7 +204,7 @@ impl<'a> Env<'a> {
/// There's no way to run Erlang code in an `OwnedEnv`. It's not a process. It's just a workspace
/// for building terms.
pub struct OwnedEnv {
env: Arc<NIF_ENV>,
env: Arc<*mut ErlNifEnv>,
}

unsafe impl Send for OwnedEnv {}
Expand Down Expand Up @@ -331,8 +333,8 @@ impl Drop for OwnedEnv {
/// example.
#[derive(Clone)]
pub struct SavedTerm {
env_generation: Weak<NIF_ENV>,
term: NIF_TERM,
env_generation: Weak<*mut ErlNifEnv>,
term: ErlNifTerm,
}

unsafe impl Send for SavedTerm {}
Expand Down
13 changes: 8 additions & 5 deletions rustler/src/nif.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
use crate::codegen_runtime::{c_char, c_int, c_uint, DEF_NIF_FUNC, NIF_ENV, NIF_TERM};
use crate::sys::{c_char, c_int, c_uint, ErlNifEnv, ErlNifFunc, ErlNifTerm};

pub struct Nif {
pub name: *const c_char,
pub arity: c_uint,
pub flags: c_uint,
// pub func: DEF_NIF_FUNC,
pub raw_func:
unsafe extern "C" fn(nif_env: NIF_ENV, argc: c_int, argv: *const NIF_TERM) -> NIF_TERM,
pub raw_func: unsafe extern "C" fn(
nif_env: *mut ErlNifEnv,
argc: c_int,
argv: *const ErlNifTerm,
) -> ErlNifTerm,
}

impl Nif {
pub fn get_def(&self) -> DEF_NIF_FUNC {
DEF_NIF_FUNC {
pub fn get_def(&self) -> ErlNifFunc {
ErlNifFunc {
arity: self.arity,
flags: self.flags,
function: self.raw_func,
Expand Down
5 changes: 4 additions & 1 deletion rustler/src/sys/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
use super::nif_filler::{self, DynNifFiller};
use super::types::*;

#[allow(non_camel_case_types)]
type ERL_NIF_TERM = ErlNifTerm;

static mut DYN_NIF_CALLBACKS: DynNifCallbacks =
unsafe { std::mem::MaybeUninit::zeroed().assume_init() };

Expand All @@ -26,7 +29,7 @@ pub unsafe fn internal_write_symbols() {
}

/// See [enif_make_pid](http://erlang.org/doc/man/erl_nif.html#enif_make_pid) in the Erlang docs
pub unsafe fn enif_make_pid(_env: *mut ErlNifEnv, pid: ErlNifPid) -> ERL_NIF_TERM {
pub unsafe fn enif_make_pid(_env: *mut ErlNifEnv, pid: ErlNifPid) -> ErlNifTerm {
pid.pid
}

Expand Down
35 changes: 18 additions & 17 deletions rustler/src/sys/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@ use std::os;
#[allow(non_camel_case_types)]
pub type size_t = usize;

//use std::mem::size_of;

#[allow(non_camel_case_types)]
pub type ERL_NIF_UINT = size_t;

#[allow(non_camel_case_types)]
pub type ERL_NIF_TERM = ERL_NIF_UINT;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
#[repr(transparent)]
pub struct ErlNifTerm(ERL_NIF_UINT);

//#[derive(Debug, Copy, Clone)]
//#[repr(C)]
//pub struct ERL_NIF_TERM(ERL_NIF_UINT); // Don't do this, 32 bit calling convention is different for structs and ints.
impl std::fmt::Display for ErlNifTerm {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

/// See [ErlNifEnv](http://www.erlang.org/doc/man/erl_nif.html#ErlNifEnv) in the Erlang docs.
#[derive(Debug)]
Expand All @@ -43,8 +44,8 @@ pub struct ErlNifFunc {
pub function: unsafe extern "C" fn(
env: *mut ErlNifEnv,
argc: c_int,
argv: *const ERL_NIF_TERM,
) -> ERL_NIF_TERM,
argv: *const ErlNifTerm,
) -> ErlNifTerm,
pub flags: c_uint,
}

Expand All @@ -63,22 +64,22 @@ pub struct ErlNifEntry {
unsafe extern "C" fn(
env: *mut ErlNifEnv,
priv_data: *mut *mut c_void,
load_info: ERL_NIF_TERM,
load_info: ErlNifTerm,
) -> c_int,
>,
pub reload: Option<
unsafe extern "C" fn(
env: *mut ErlNifEnv,
priv_data: *mut *mut c_void,
load_info: ERL_NIF_TERM,
load_info: ErlNifTerm,
) -> c_int,
>,
pub upgrade: Option<
unsafe extern "C" fn(
env: *mut ErlNifEnv,
priv_data: *mut *mut c_void,
old_priv_data: *mut *mut c_void,
load_info: ERL_NIF_TERM,
load_info: ErlNifTerm,
) -> c_int,
>,
pub unload: Option<unsafe extern "C" fn(env: *mut ErlNifEnv, priv_data: *mut c_void) -> ()>,
Expand Down Expand Up @@ -204,7 +205,7 @@ pub enum ErlNifCharEncoding {
#[derive(Debug, Copy, Clone)]
#[repr(C)]
pub struct ErlNifPid {
pub(crate) pid: ERL_NIF_TERM,
pub(crate) pid: ErlNifTerm,
}

/// See [ErlNifSysInfo](http://www.erlang.org/doc/man/erl_nif.html#ErlNifSysInfo) in the Erlang docs.
Expand Down Expand Up @@ -240,11 +241,11 @@ pub const ERL_NIF_DIRTY_JOB_IO_BOUND: ErlNifDirtyTaskFlags = 2;
#[allow(missing_copy_implementations)]
#[repr(C)]
pub struct ErlNifMapIterator {
map: ERL_NIF_TERM,
map: ErlNifTerm,
t_limit: ERL_NIF_UINT,
idx: ERL_NIF_UINT,
ks: *mut ERL_NIF_TERM,
vs: *mut ERL_NIF_TERM,
ks: *mut ErlNifTerm,
vs: *mut ErlNifTerm,
__spare__: [*mut c_void; 2],
}

Expand Down Expand Up @@ -288,7 +289,7 @@ pub const ERL_NIF_UNIQUE_MONOTONIC: ErlNifUniqueInteger = 1 << 1;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct ErlNifPort {
port_id: ERL_NIF_TERM, // internal, may change
port_id: ErlNifTerm, // internal, may change
}
// ref https://github.com/erlang/otp/blob/maint/erts/emulator/beam/erl_nif.h#L155

Expand Down
11 changes: 5 additions & 6 deletions rustler/src/term.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::sys::*;
use crate::types::binary::OwnedBinary;
use crate::wrapper::env::term_to_binary;
use crate::wrapper::NIF_TERM;
use crate::{Binary, Decoder, Env, NifResult};
use std::cmp::Ordering;
use std::fmt::{self, Debug};
Expand All @@ -13,7 +12,7 @@ use std::hash::{Hash, Hasher};
/// that owns it.
#[derive(Clone, Copy)]
pub struct Term<'a> {
term: NIF_TERM,
term: ErlNifTerm,
env: Env<'a>,
}

Expand All @@ -24,19 +23,19 @@ impl Debug for Term<'_> {
}

impl<'a> Term<'a> {
/// Create a `Term` from a raw `NIF_TERM`.
/// Create a `Term` from a raw `ErlNifTerm`.
///
/// # Unsafe
/// The caller must ensure that `env` is the environment that `inner` belongs to,
/// unless `inner` is an atom term.
#[inline]
pub unsafe fn new(env: Env<'a>, inner: NIF_TERM) -> Self {
pub unsafe fn new(env: Env<'a>, inner: ErlNifTerm) -> Self {
Term { term: inner, env }
}
/// This extracts the raw term pointer. It is usually used in order to obtain a type that can
/// This extracts the raw term. It is usually used in order to obtain a type that can
/// be passed to calls into the erlang vm.
#[inline]
pub fn as_c_arg(&self) -> NIF_TERM {
pub fn as_c_arg(&self) -> ErlNifTerm {
self.term
}

Expand Down
10 changes: 5 additions & 5 deletions rustler/src/types/atom.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
use crate::sys::ErlNifCharEncoding;
use crate::sys::{ErlNifCharEncoding, ErlNifTerm};
use crate::wrapper::atom;
use crate::wrapper::NIF_TERM;
use crate::{Decoder, Encoder, Env, Error, NifResult, Term};
use std::fmt;
use std::hash::{Hash, Hasher};

// Atoms are a special case of a term. They can be stored and used on all envs regardless of where
// it lives and when it is created.
#[derive(PartialEq, Eq, Clone, Copy)]
#[repr(transparent)]
pub struct Atom {
term: NIF_TERM,
term: ErlNifTerm,
}

impl Atom {
pub fn as_c_arg(self) -> NIF_TERM {
pub fn as_c_arg(self) -> ErlNifTerm {
self.term
}

Expand All @@ -22,7 +22,7 @@ impl Atom {
unsafe { Term::new(env, self.term) }
}

unsafe fn from_nif_term(term: NIF_TERM) -> Self {
unsafe fn from_nif_term(term: ErlNifTerm) -> Self {
Self { term }
}

Expand Down
9 changes: 5 additions & 4 deletions rustler/src/types/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
//!
//! Right now the only supported way to read lists are through the ListIterator.

use crate::wrapper::{list, NIF_TERM};
use crate::sys::ErlNifTerm;
use crate::wrapper::list;
use crate::{Decoder, Encoder, Env, Error, NifResult, Term};

/// Enables iteration over the items in the list.
Expand Down Expand Up @@ -90,7 +91,7 @@ impl<'a> Decoder<'a> for ListIterator<'a> {

//impl<'a, T> Encoder for Iterator<Item = T> where T: Encoder {
// fn encode<'b>(&self, env: Env<'b>) -> Term<'b> {
// let term_arr: Vec<NIF_TERM> =
// let term_arr: Vec<ErlNifTerm> =
// self.map(|x| x.encode(env).as_c_arg()).collect();
// }
//}
Expand Down Expand Up @@ -122,7 +123,7 @@ where
{
#[inline]
fn encode<'b>(&self, env: Env<'b>) -> Term<'b> {
let term_array: Vec<NIF_TERM> = self.iter().map(|x| x.encode(env).as_c_arg()).collect();
let term_array: Vec<ErlNifTerm> = self.iter().map(|x| x.encode(env).as_c_arg()).collect();
unsafe { Term::new(env, list::make_list(env.as_c_arg(), &term_array)) }
}
}
Expand All @@ -133,7 +134,7 @@ where
{
#[inline]
fn encode<'b>(&self, env: Env<'b>) -> Term<'b> {
let term_array: Vec<NIF_TERM> = self.iter().map(|x| x.encode(env).as_c_arg()).collect();
let term_array: Vec<ErlNifTerm> = self.iter().map(|x| x.encode(env).as_c_arg()).collect();
unsafe { Term::new(env, list::make_list(env.as_c_arg(), &term_array)) }
}
}
Expand Down
Loading
Loading