Skip to content

Commit

Permalink
cargo fmt (rusterlium#143)
Browse files Browse the repository at this point in the history
Signed-off-by: Sonny Scroggin <[email protected]>
  • Loading branch information
scrogson authored and azdlowry committed Jul 11, 2018
1 parent 5a142f6 commit 3d2fdd6
Show file tree
Hide file tree
Showing 33 changed files with 521 additions and 299 deletions.
63 changes: 36 additions & 27 deletions src/codegen_runtime.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
//! Functions used by runtime generated code. Should not be used.
use ::{Env, Term};
use std::panic::catch_unwind;
use ::types::atom::Atom;
use ::wrapper::exception;
use ::NifResult;
use types::atom::Atom;
use wrapper::exception;
use NifResult;
use {Env, Term};

// Names used by the `rustler_export_nifs!` macro or other generated code.
pub use ::wrapper::nif_interface::{
c_int, c_void, DEF_NIF_ENTRY, DEF_NIF_FUNC,
NIF_ENV, NIF_TERM, NIF_MAJOR_VERSION, NIF_MINOR_VERSION,
MUTABLE_NIF_RESOURCE_HANDLE, get_nif_resource_type_init_size };
pub use wrapper::nif_interface::{c_int, 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};

#[cfg(windows)]
pub use ::erlang_nif_sys::{ TWinDynNifCallbacks, WIN_DYN_NIF_CALLBACKS };
pub use erlang_nif_sys::{TWinDynNifCallbacks, WIN_DYN_NIF_CALLBACKS};

/// This is the last level of rust safe rust code before the BEAM.
/// No panics should go above this point, as they will unwrap into the C code and ruin the day.
Expand All @@ -22,43 +21,53 @@ pub use ::erlang_nif_sys::{ TWinDynNifCallbacks, WIN_DYN_NIF_CALLBACKS };
///
/// This takes arguments, including raw pointers, that must be correct. Only the glue code
/// generated by `rustler_export_nifs!` can call this function correctly.
pub unsafe fn handle_nif_call(function: for<'a> fn(Env<'a>, &[Term<'a>]) -> NifResult<Term<'a>>,
_arity: usize, r_env: NIF_ENV,
argc: c_int, argv: *const NIF_TERM) -> NIF_TERM {
pub unsafe fn handle_nif_call(
function: for<'a> fn(Env<'a>, &[Term<'a>]) -> NifResult<Term<'a>>,
_arity: usize,
r_env: NIF_ENV,
argc: c_int,
argv: *const NIF_TERM,
) -> NIF_TERM {
let env_lifetime = ();
let env = Env::new(&env_lifetime, r_env);

let terms = ::std::slice::from_raw_parts(argv, argc as usize).iter()
.map(|x| Term::new(env, *x)).collect::<Vec<Term>>();
let terms = ::std::slice::from_raw_parts(argv, argc as usize)
.iter()
.map(|x| Term::new(env, *x))
.collect::<Vec<Term>>();

let result: ::std::thread::Result<NIF_TERM> = catch_unwind(|| {
match function(env, &terms) {
Ok(ret) => ret.as_c_arg(),
Err(err) => err.encode(env).as_c_arg(),
}
let result: ::std::thread::Result<NIF_TERM> = catch_unwind(|| match function(env, &terms) {
Ok(ret) => ret.as_c_arg(),
Err(err) => err.encode(env).as_c_arg(),
});

match result {
Ok(res) => res,
Err(_err) =>
exception::raise_exception(
env.as_c_arg(),
Atom::from_bytes(env, b"nif_panic").ok().unwrap().as_c_arg()),
Err(_err) => exception::raise_exception(
env.as_c_arg(),
Atom::from_bytes(env, b"nif_panic").ok().unwrap().as_c_arg(),
),
}
}

/// # Unsafe
///
/// This takes arguments, including raw pointers, that must be correct.
pub unsafe fn handle_nif_init_call(function: Option<for<'a> fn(Env<'a>, Term<'a>) -> bool>,
r_env: NIF_ENV,
load_info: NIF_TERM) -> c_int {
pub unsafe fn handle_nif_init_call(
function: Option<for<'a> fn(Env<'a>, Term<'a>) -> bool>,
r_env: NIF_ENV,
load_info: NIF_TERM,
) -> c_int {
let env_lifetime = ();
let env = Env::new(&env_lifetime, r_env);
let term = Term::new(env, load_info);

if let Some(inner) = function {
if inner(env, term) { 0 } else { 1 }
if inner(env, term) {
0
} else {
1
}
} else {
0
}
Expand Down
8 changes: 3 additions & 5 deletions src/dynamic.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use ::{Term};
use ::wrapper::check;
use wrapper::check;
use Term;

pub enum TermType {
Atom,
Expand All @@ -14,7 +14,7 @@ pub enum TermType {
Port,
Ref,
Tuple,
Unknown
Unknown,
}

pub fn get_type(term: Term) -> TermType {
Expand Down Expand Up @@ -57,7 +57,6 @@ macro_rules! impl_check {

/// ## Type checks
impl<'a> Term<'a> {

/// Returns an enum representing which type the term is.
/// Note that using the individual `is_*` functions is more
/// efficient for checking a single type.
Expand All @@ -77,5 +76,4 @@ impl<'a> Term<'a> {
impl_check!(is_port);
impl_check!(is_ref);
impl_check!(is_tuple);

}
8 changes: 4 additions & 4 deletions src/env.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use {Encoder, Term};
use wrapper::nif_interface::{self, NIF_ENV, NIF_TERM};
use types::pid::Pid;
use std::marker::PhantomData;
use std::ptr;
use std::sync::{Arc, Weak};
use std::marker::PhantomData;
use types::pid::Pid;
use wrapper::nif_interface::{self, NIF_ENV, NIF_TERM};
use {Encoder, Term};

/// Private type system hack to help ensure that each environment exposed to safe Rust code is
/// given a different lifetime. The size of this type is zero, so it costs nothing at run time. Its
Expand Down
2 changes: 1 addition & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use {Encoder, Env, Term, types, wrapper};
use {types, wrapper, Encoder, Env, Term};

/// Represents usual errors that can happen in a nif. This enables you
/// to return an error from anywhere, even places where you don't have
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ pub mod env;
pub use env::Env;
pub mod thread;

mod export;
pub mod error;
mod export;
pub use error::Error;

pub type NifResult<T> = Result<T, Error>;
97 changes: 75 additions & 22 deletions src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@
//! NIF calls. The struct will be automatically dropped when the BEAM GC decides that there are no
//! more references to the resource.
use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::ops::Deref;
use std::marker::PhantomData;
use std::ptr;

use super::{ Term, Env, Error, Encoder, Decoder, NifResult };
use ::wrapper::nif_interface::{ NIF_RESOURCE_TYPE, MUTABLE_NIF_RESOURCE_HANDLE, NIF_ENV, NifResourceFlags };
use ::wrapper::nif_interface::{ c_void };
use super::{Decoder, Encoder, Env, Error, NifResult, Term};
use wrapper::nif_interface::c_void;
use wrapper::nif_interface::{NifResourceFlags, MUTABLE_NIF_RESOURCE_HANDLE, NIF_ENV,
NIF_RESOURCE_TYPE};

/// Re-export a type used by the `resource_struct_init!` macro.
#[doc(hidden)]
pub use ::wrapper::nif_interface::NIF_RESOURCE_FLAGS;
pub use wrapper::nif_interface::NIF_RESOURCE_FLAGS;

/// The ResourceType struct contains a NIF_RESOURCE_TYPE and a phantom reference to the type it
/// is for. It serves as a holder for the information needed to interact with the Erlang VM about
Expand All @@ -37,12 +38,18 @@ pub trait ResourceTypeProvider: Sized + Send + Sync + 'static {
fn get_type() -> &'static ResourceType<Self>;
}

impl<T> Encoder for ResourceArc<T> where T: ResourceTypeProvider {
impl<T> Encoder for ResourceArc<T>
where
T: ResourceTypeProvider,
{
fn encode<'a>(&self, env: Env<'a>) -> Term<'a> {
self.as_term(env)
}
}
impl<'a, T> Decoder<'a> for ResourceArc<T> where T: ResourceTypeProvider + 'a {
impl<'a, T> Decoder<'a> for ResourceArc<T>
where
T: ResourceTypeProvider + 'a,
{
fn decode(term: Term<'a>) -> NifResult<Self> {
ResourceArc::from_term(term)
}
Expand All @@ -65,10 +72,18 @@ extern "C" fn resource_destructor<T>(_env: NIF_ENV, handle: MUTABLE_NIF_RESOURCE
///
/// Panics if `name` isn't null-terminated.
#[doc(hidden)]
pub fn open_struct_resource_type<'a, T: ResourceTypeProvider>(env: Env<'a>, name: &str,
flags: NifResourceFlags) -> Option<ResourceType<T>> {
pub fn open_struct_resource_type<'a, T: ResourceTypeProvider>(
env: Env<'a>,
name: &str,
flags: NifResourceFlags,
) -> Option<ResourceType<T>> {
let res: Option<NIF_RESOURCE_TYPE> = unsafe {
::wrapper::resource::open_resource_type(env.as_c_arg(), name.as_bytes(), Some(resource_destructor::<T>), flags)
::wrapper::resource::open_resource_type(
env.as_c_arg(),
name.as_bytes(),
Some(resource_destructor::<T>),
flags,
)
};
if res.is_some() {
Some(ResourceType {
Expand Down Expand Up @@ -101,16 +116,30 @@ unsafe fn align_alloced_mem_for_struct<T>(ptr: *const c_void) -> *const c_void {
/// Rust code and Erlang code can both have references to the same resource at the same time. Rust
/// code uses `ResourceArc`; in Erlang, a reference to a resource is a kind of term. You can
/// convert back and forth between the two using `Encoder` and `Decoder`.
pub struct ResourceArc<T> where T: ResourceTypeProvider {
pub struct ResourceArc<T>
where
T: ResourceTypeProvider,
{
raw: *const c_void,
inner: *mut T,
}

// Safe because T is `Sync` and `Send`.
unsafe impl<T> Send for ResourceArc<T> where T: ResourceTypeProvider {}
unsafe impl<T> Sync for ResourceArc<T> where T: ResourceTypeProvider {}
unsafe impl<T> Send for ResourceArc<T>
where
T: ResourceTypeProvider,
{
}
unsafe impl<T> Sync for ResourceArc<T>
where
T: ResourceTypeProvider,
{
}

impl<T> ResourceArc<T> where T: ResourceTypeProvider {
impl<T> ResourceArc<T>
where
T: ResourceTypeProvider,
{
/// Makes a new ResourceArc from the given type. Note that the type must have
/// ResourceTypeProvider implemented for it. See module documentation for info on this.
pub fn new(data: T) -> Self {
Expand All @@ -127,11 +156,19 @@ impl<T> ResourceArc<T> where T: ResourceTypeProvider {
}

fn from_term(term: Term) -> Result<Self, Error> {
let res_resource = match unsafe { ::wrapper::resource::get_resource(term.get_env().as_c_arg(), term.as_c_arg(), T::get_type().res) } {
let res_resource = match unsafe {
::wrapper::resource::get_resource(
term.get_env().as_c_arg(),
term.as_c_arg(),
T::get_type().res,
)
} {
Some(res) => res,
None => return Err(Error::BadArg),
};
unsafe { ::wrapper::resource::keep_resource(res_resource); }
unsafe {
::wrapper::resource::keep_resource(res_resource);
}
let casted_ptr = unsafe { align_alloced_mem_for_struct::<T>(res_resource) as *mut T };
Ok(ResourceArc {
raw: res_resource,
Expand All @@ -140,7 +177,12 @@ impl<T> ResourceArc<T> where T: ResourceTypeProvider {
}

fn as_term<'a>(&self, env: Env<'a>) -> Term<'a> {
unsafe { Term::new(env, ::wrapper::resource::make_resource(env.as_c_arg(), self.raw)) }
unsafe {
Term::new(
env,
::wrapper::resource::make_resource(env.as_c_arg(), self.raw),
)
}
}

fn as_c_arg(&mut self) -> *const c_void {
Expand All @@ -152,27 +194,38 @@ impl<T> ResourceArc<T> where T: ResourceTypeProvider {
}
}

impl<T> Deref for ResourceArc<T> where T: ResourceTypeProvider {
impl<T> Deref for ResourceArc<T>
where
T: ResourceTypeProvider,
{
type Target = T;

fn deref(&self) -> &T {
self.inner()
}
}

impl<T> Clone for ResourceArc<T> where T: ResourceTypeProvider {
impl<T> Clone for ResourceArc<T>
where
T: ResourceTypeProvider,
{
/// Cloning a `ResourceArc` simply increments the reference count for the
/// resource. The `T` value is not cloned.
fn clone(&self) -> Self {
unsafe { ::wrapper::resource::keep_resource(self.raw); }
unsafe {
::wrapper::resource::keep_resource(self.raw);
}
ResourceArc {
raw: self.raw,
inner: self.inner,
}
}
}

impl<T> Drop for ResourceArc<T> where T: ResourceTypeProvider {
impl<T> Drop for ResourceArc<T>
where
T: ResourceTypeProvider,
{
/// When a `ResourceArc` is dropped, the reference count is decremented. If
/// there are no other references to the resource, the `T` value is dropped.
///
Expand Down
2 changes: 1 addition & 1 deletion src/schedule.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::Env;
use super::wrapper::nif_interface::enif_consume_timeslice;
use super::Env;

pub enum SchedulerFlags {
Normal = 0,
Expand Down
19 changes: 10 additions & 9 deletions src/term.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use ::{Decoder, Env, NifResult};
use ::wrapper::nif_interface::NIF_TERM;
use ::wrapper::env::term_to_binary;
use ::types::binary::Binary;
use std::fmt::{self, Debug};
use std::cmp::Ordering;
use std::fmt::{self, Debug};
use types::binary::Binary;
use wrapper::env::term_to_binary;
use wrapper::nif_interface::NIF_TERM;
use {Decoder, Env, NifResult};

/// Term is used to represent all erlang terms. Terms are always lifetime limited by a Env.
///
Expand All @@ -22,7 +22,6 @@ impl<'a> Debug for Term<'a> {
}

impl<'a> Term<'a> {

/// Create a `Term` from a raw `NIF_TERM`.
///
/// # Unsafe
Expand Down Expand Up @@ -70,7 +69,10 @@ impl<'a> Term<'a> {
/// let term: Term = ...;
/// let number: i32 = try!(term.decode());
/// ```
pub fn decode<T>(self) -> NifResult<T> where T: Decoder<'a> {
pub fn decode<T>(self) -> NifResult<T>
where
T: Decoder<'a>,
{
Decoder::decode(self)
}

Expand All @@ -90,8 +92,7 @@ impl<'a> PartialEq for Term<'a> {
impl<'a> Eq for Term<'a> {}

fn cmp(lhs: &Term, rhs: &Term) -> Ordering {
let ord = unsafe { ::wrapper::nif_interface::enif_compare(
lhs.as_c_arg(), rhs.as_c_arg()) };
let ord = unsafe { ::wrapper::nif_interface::enif_compare(lhs.as_c_arg(), rhs.as_c_arg()) };
match ord {
0 => Ordering::Equal,
n if n < 0 => Ordering::Less,
Expand Down
Loading

0 comments on commit 3d2fdd6

Please sign in to comment.