Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic Loading #646

Merged
merged 5 commits into from
Dec 4, 2020
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ legacy-runtime = ["neon-runtime/neon-sys", "neon-build/neon-sys"]

# Feature flag to enable the experimental N-API runtime. For now, this feature
# is disabled by default.
napi-runtime = ["proc-macros", "neon-macros/napi", "neon-runtime/nodejs-sys"]
napi-runtime = ["proc-macros", "neon-macros/napi", "neon-runtime/napi"]

# Feature flag to disable external dependencies on docs build
docs-only = ["neon-runtime/docs-only"]
Expand Down
6 changes: 3 additions & 3 deletions crates/neon-macros/src/napi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ pub(crate) fn main(
#vis #sig {
#[no_mangle]
unsafe extern "C" fn napi_register_module_v1(
env: ::neon::macro_internal::runtime::nodejs_sys::napi_env,
m: ::neon::macro_internal::runtime::nodejs_sys::napi_value,
) -> ::neon::macro_internal::runtime::nodejs_sys::napi_value {
env: ::neon::macro_internal::runtime::raw::Env,
m: ::neon::macro_internal::runtime::raw::Local,
) -> ::neon::macro_internal::runtime::raw::Local {
::neon::macro_internal::initialize_module(
env,
::std::mem::transmute(m),
Expand Down
7 changes: 6 additions & 1 deletion crates/neon-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ authors = ["Dave Herman <[email protected]>"]
description = "Bindings to the Node.js native addon API, used by the Neon implementation."
repository = "https://github.com/neon-bindings/neon"
license = "MIT/Apache-2.0"
edition = "2018"

[dependencies]
cfg-if = "0.1.9"
libloading = { version = "0.6.5", optional = true }
neon-sys = { version = "=0.5.3", path = "../neon-sys", optional = true }
nodejs-sys = { version = "0.7.0", optional = true }
smallvec = "1.4.2"

[dev-dependencies]
nodejs-sys = "0.7.0" # Dev dependency for easy copying
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe be even more explicit in the comment, like "Not strictly needed; just here for easy manual copying"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


[features]
default = []
napi = ["libloading"]
docs-only = ["neon-sys/docs-only"]

[package.metadata.docs.rs]
Expand Down
17 changes: 6 additions & 11 deletions crates/neon-runtime/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
extern crate cfg_if;
extern crate smallvec;

#[cfg(all(not(feature = "neon-sys"), not(feature = "nodejs-sys")))]
compile_error!("The Neon runtime must have at least one of the `neon-sys` or `nodejs-sys` backends enabled.");
#[cfg(all(not(feature = "neon-sys"), not(feature = "napi")))]
compile_error!("The Neon runtime must have at least one of the `neon-sys` or `napi` backends enabled.");

use cfg_if::cfg_if;

cfg_if! {
if #[cfg(feature = "nodejs-sys")] {
pub extern crate nodejs_sys;
if #[cfg(feature = "napi")] {
pub mod napi;
}
}

cfg_if! {
if #[cfg(feature = "neon-sys")] {
extern crate neon_sys;
pub mod nan;
// The legacy variant is the default API as long as it's present.
pub use nan::*;
} else if #[cfg(feature = "nodejs-sys")] {
pub use crate::nan::*;
} else if #[cfg(feature = "napi")] {
// The N-API variant is only the default API if the legacy variant is disabled.
pub use napi::*;
pub use crate::napi::*;
}
}
2 changes: 1 addition & 1 deletion crates/neon-runtime/src/nan/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Facilities for creating and throwing JS errors.

use raw::{Isolate, Local};
use crate::raw::{Isolate, Local};

/// Throws an `Error` object in the current context.
pub unsafe fn throw(_: Isolate, val: Local) {
Expand Down
6 changes: 3 additions & 3 deletions crates/neon-runtime/src/nan/scope.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//! Facilities for working with `v8::HandleScope`s and `v8::EscapableHandleScope`s.

use raw::{HandleScope, EscapableHandleScope, InheritedHandleScope, Isolate};
use crate::raw::{HandleScope, EscapableHandleScope, InheritedHandleScope, Isolate};

pub trait Root {
unsafe fn allocate() -> Self;
unsafe fn enter(&mut self, Isolate);
unsafe fn exit(&mut self, Isolate);
unsafe fn enter(&mut self, _: Isolate);
unsafe fn exit(&mut self, _: Isolate);
}

impl Root for HandleScope {
Expand Down
12 changes: 6 additions & 6 deletions crates/neon-runtime/src/napi/array.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//! Facilities for working with Array `napi_value`s.

use raw::{Env, Local};
use crate::raw::{Env, Local};

use nodejs_sys as napi;
use crate::napi::bindings as napi;

pub unsafe extern "C" fn new(out: &mut Local, env: Env, length: u32) {
assert_eq!(
napi::napi_create_array_with_length(env, length as usize, out as *mut _),
napi::napi_status::napi_ok,
napi::create_array_with_length(env, length as usize, out as *mut _),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These naming conventions aren't, like, gonna change the world, but they're so nice 😎

Copy link
Member Author

@kjvalencik kjvalencik Dec 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's not to love about repeating the word napi 3x in a single identifier? 😆 s/napi::napi_status::napi_ok/napi::Status::Ok/

napi, napi.... napi.

...napi

napi::Status::Ok,
);
}

Expand All @@ -19,8 +19,8 @@ pub unsafe extern "C" fn new(out: &mut Local, env: Env, length: u32) {
pub unsafe extern "C" fn len(env: Env, array: Local) -> u32 {
let mut len = 0;
assert_eq!(
napi::napi_get_array_length(env, array, &mut len as *mut _),
napi::napi_status::napi_ok
napi::get_array_length(env, array, &mut len as *mut _),
napi::Status::Ok
);
len
}
12 changes: 6 additions & 6 deletions crates/neon-runtime/src/napi/arraybuffer.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
use raw::{Env, Local};
use crate::raw::{Env, Local};
use std::os::raw::c_void;
use std::ptr::null_mut;

use nodejs_sys as napi;
use crate::napi::bindings as napi;

pub unsafe extern "C" fn new(out: &mut Local, env: Env, size: u32) -> bool {
let status = napi::napi_create_arraybuffer(env, size as usize, null_mut(), out as *mut _);
let status = napi::create_arraybuffer(env, size as usize, null_mut(), out as *mut _);

status == napi::napi_status::napi_ok
status == napi::Status::Ok
}

pub unsafe extern "C" fn data<'a, 'b>(env: Env, base_out: &'a mut *mut c_void, obj: Local) -> usize {
let mut size = 0;
assert_eq!(
napi::napi_get_arraybuffer_info(env, obj, base_out as *mut _, &mut size as *mut _),
napi::napi_status::napi_ok,
napi::get_arraybuffer_info(env, obj, base_out as *mut _, &mut size as *mut _),
napi::Status::Ok,
);
size
}
204 changes: 204 additions & 0 deletions crates/neon-runtime/src/napi/bindings/functions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
#[cfg(windows)]
use libloading::os::windows::Library;
#[cfg(not(windows))]
use libloading::os::unix::Library;

use std::os::raw::{c_char, c_void};
use super::types::*;

generate!(extern "C" {
fn get_undefined(env: Env, result: *mut Value) -> Status;

fn get_null(env: Env, result: *mut Value) -> Status;

fn get_global(env: Env, result: *mut Value) -> Status;

fn get_boolean(env: Env, value: bool, result: *mut Value) -> Status;

fn create_double(env: Env, value: f64, result: *mut Value) -> Status;

fn create_object(env: Env, result: *mut Value) -> Status;

fn get_value_bool(env: Env, value: Value, result: *mut bool) -> Status;

fn get_value_double(env: Env, value: Value, result: *mut f64) -> Status;

fn create_array_with_length(env: Env, length: usize, result: *mut Value) -> Status;

fn get_array_length(env: Env, value: Value, result: *mut u32)-> Status;

fn get_new_target(env: Env, cbinfo: CallbackInfo, result: *mut Value) -> Status;

fn coerce_to_object(env: Env, value: Value, result: *mut Value) -> Status;

fn coerce_to_string(env: Env, value: Value, result: *mut Value) -> Status;

fn throw(env: Env, error: Value) -> Status;

fn create_error(env: Env, code: Value, msg: Value, result: *mut Value) -> Status;

fn get_and_clear_last_exception(env: Env, result: *mut Value) -> Status;

fn is_exception_pending(env: Env, result: *mut bool) -> Status;

fn get_value_external(env: Env, value: Value, result: *mut *mut c_void) -> Status;

fn typeof_value(env: Env, value: Value, result: *mut ValueType) -> Status;

fn close_escapable_handle_scope(env: Env, scope: EscapableHandleScope) -> Status;

fn open_escapable_handle_scope(env: Env, result: *mut EscapableHandleScope) -> Status;

fn open_handle_scope(env: Env, result: *mut HandleScope) -> Status;

fn close_handle_scope(env: Env, scope: HandleScope) -> Status;

fn is_arraybuffer(env: Env, value: Value, result: *mut bool) -> Status;
fn is_buffer(env: Env, value: Value, result: *mut bool) -> Status;
fn is_error(env: Env, value: Value, result: *mut bool) -> Status;
fn is_array(env: Env, value: Value, result: *mut bool) -> Status;

fn get_value_string_utf8(
env: Env,
value: Value,
buf: *mut c_char,
bufsize: usize,
result: *mut usize,
) -> Status;

fn create_type_error(
env: Env,
code: Value,
msg: Value,
result: *mut Value,
) -> Status;

fn create_range_error(
env: Env,
code: Value,
msg: Value,
result: *mut Value,
) -> Status;

fn create_string_utf8(
env: Env,
str: *const c_char,
length: usize,
result: *mut Value,
) -> Status;

fn create_arraybuffer(
env: Env,
byte_length: usize,
data: *mut *mut c_void,
result: *mut Value,
) -> Status;

fn get_arraybuffer_info(
env: Env,
arraybuffer: Value,
data: *mut *mut c_void,
byte_length: *mut usize,
) -> Status;

fn create_buffer(
env: Env,
length: usize,
data: *mut *mut c_void,
result: *mut Value,
) -> Status;

fn get_buffer_info(
env: Env,
value: Value,
data: *mut *mut c_void,
length: *mut usize,
) -> Status;

fn get_cb_info(
env: Env,
cbinfo: CallbackInfo,
argc: *mut usize,
argv: *mut Value,
this_arg: *mut Value,
data: *mut *mut c_void,
) -> Status;

fn create_external(
env: Env,
data: *mut c_void,
finalize_cb: Finalize,
finalize_hint: *mut c_void,
result: *mut Value,
) -> Status;

fn new_instance(
env: Env,
constructor: Value,
argc: usize,
argv: *const Value,
result: *mut Value,
) -> Status;

fn call_function(
env: Env,
recv: Value,
func: Value,
argc: usize,
argv: *const Value,
result: *mut Value,
) -> Status;

fn create_function(
env: Env,
utf8name: *const c_char,
length: usize,
cb: Callback,
data: *mut c_void,
result: *mut Value,
) -> Status;

fn set_property(
env: Env,
object: Value,
key: Value,
value: Value,
) -> Status;

fn get_property(
env: Env,
object: Value,
key: Value,
result: *mut Value,
) -> Status;

fn set_element(
env: Env,
object: Value,
index: u32,
value: Value,
) -> Status;

fn get_element(
env: Env,
object: Value,
index: u32,
result: *mut Value,
) -> Status;

fn get_all_property_names(
env: Env,
object: Value,
key_mode: KeyCollectionMode,
key_filter: KeyFilter,
key_conversion: KeyConversion,
result: *mut Value,
) -> Status;

fn escape_handle(
env: Env,
scope: EscapableHandleScope,
escapee: Value,
result: *mut Value,
) -> Status;
});
Loading