-
Notifications
You must be signed in to change notification settings - Fork 228
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
658 additions
and
293 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
use crate::codegen_runtime::{c_int, DEF_NIF_FUNC, NIF_ENV, NIF_TERM}; | ||
|
||
pub trait Nif { | ||
const NAME: *const u8; | ||
const ARITY: u32; | ||
const FLAGS: u32; | ||
const FUNC: DEF_NIF_FUNC; | ||
const RAW_FUNC: unsafe extern "C" fn( | ||
nif_env: NIF_ENV, | ||
argc: c_int, | ||
argv: *const NIF_TERM, | ||
) -> NIF_TERM; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
use proc_macro2::TokenStream; | ||
use quote::quote; | ||
use syn::parse::{Parse, ParseStream}; | ||
use syn::punctuated::Punctuated; | ||
use syn::token::Comma; | ||
use syn::{Expr, Result, Token}; | ||
|
||
#[derive(Debug)] | ||
pub struct InitMacroInput { | ||
module: syn::Lit, | ||
funcs: syn::ExprArray, | ||
on_load: Option<TokenStream>, | ||
} | ||
|
||
impl Parse for InitMacroInput { | ||
fn parse(input: ParseStream) -> Result<Self> { | ||
let module = syn::Lit::parse(input)?; | ||
let _comma = <syn::Token![,]>::parse(input)?; | ||
let funcs = syn::ExprArray::parse(input)?; | ||
let on_load = if input.peek(Token![,]) { | ||
let _comma = <Token![,]>::parse(input)?; | ||
Some(TokenStream::parse(input)?) | ||
} else { | ||
None | ||
}; | ||
|
||
Ok(InitMacroInput { | ||
module, | ||
funcs, | ||
on_load, | ||
}) | ||
} | ||
} | ||
|
||
impl Into<proc_macro2::TokenStream> for InitMacroInput { | ||
fn into(self) -> proc_macro2::TokenStream { | ||
let name = self.module; | ||
let num_of_funcs = self.funcs.elems.len(); | ||
let funcs = nif_funcs(self.funcs.elems); | ||
let on_load = self.on_load; | ||
|
||
let inner = quote! { | ||
static mut NIF_ENTRY: Option<rustler::codegen_runtime::DEF_NIF_ENTRY> = None; | ||
const FUN_ENTRIES: &'static [rustler::codegen_runtime::DEF_NIF_FUNC] = &[ | ||
#funcs | ||
]; | ||
|
||
use rustler::Nif; | ||
|
||
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, | ||
num_of_funcs: #num_of_funcs as rustler::codegen_runtime::c_int, | ||
funcs: FUN_ENTRIES.as_ptr(), | ||
load: { | ||
extern "C" fn nif_load( | ||
env: rustler::codegen_runtime::NIF_ENV, | ||
_priv_data: *mut *mut rustler::codegen_runtime::c_void, | ||
load_info: rustler::codegen_runtime::NIF_TERM | ||
) -> rustler::codegen_runtime::c_int { | ||
unsafe { | ||
rustler::codegen_runtime::handle_nif_init_call(#on_load, env, load_info) | ||
} | ||
} | ||
Some(nif_load) | ||
}, | ||
reload: None, | ||
upgrade: None, | ||
unload: None, | ||
vm_variant: b"beam.vanilla\x00".as_ptr(), | ||
options: 0, | ||
sizeof_ErlNifResourceTypeInit: rustler::codegen_runtime::get_nif_resource_type_init_size(), | ||
}; | ||
|
||
unsafe { | ||
NIF_ENTRY = Some(entry); | ||
NIF_ENTRY.as_ref().unwrap() | ||
} | ||
}; | ||
|
||
quote! { | ||
#[cfg(unix)] | ||
#[no_mangle] | ||
pub extern "C" fn nif_init() -> *const rustler::codegen_runtime::DEF_NIF_ENTRY { | ||
#inner | ||
} | ||
|
||
#[cfg(windows)] | ||
#[no_mangle] | ||
pub extern "C" fn nif_init(callbacks: *mut rustler::codegen_runtime::TWinDynNifCallbacks) -> *const rustler::codegen_runtime::DEF_NIF_ENTRY { | ||
unsafe { | ||
rustler::codegen_runtime::WIN_DYN_NIF_CALLBACKS = Some(*callbacks); | ||
} | ||
|
||
#inner | ||
} | ||
} | ||
} | ||
} | ||
|
||
fn nif_funcs(funcs: Punctuated<Expr, Comma>) -> TokenStream { | ||
let mut tokens = TokenStream::new(); | ||
|
||
for func in funcs.iter() { | ||
if let Expr::Path(_) = *func { | ||
tokens.extend(quote!(#func::FUNC,)); | ||
} else { | ||
panic!("Expected an expression, found: {}", stringify!(func)); | ||
} | ||
} | ||
|
||
tokens | ||
} |
Oops, something went wrong.