Skip to content

Commit

Permalink
Merge pull request #507 from goto-bus-stop/functions
Browse files Browse the repository at this point in the history
Function calls
  • Loading branch information
dherman authored Jun 20, 2020
2 parents 661b5b4 + 0a40f6a commit 35c8b60
Show file tree
Hide file tree
Showing 20 changed files with 775 additions and 103 deletions.
2 changes: 1 addition & 1 deletion crates/neon-runtime/src/nan/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub use neon_sys::Neon_Call_IsConstruct as is_construct;
/// the function is bound to.
pub use neon_sys::Neon_Call_This as this;

/// Mutates the `out` argument provided to refer to the `v8::Local` handle value of the
/// Mutates the `out` argument provided to refer to the pointer value of the
/// `v8::FunctionCallbackInfo` `Data`.
pub use neon_sys::Neon_Call_Data as data;

Expand Down
75 changes: 68 additions & 7 deletions crates/neon-runtime/src/napi/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use std::os::raw::c_void;
use std::ptr::null_mut;
use raw::{FunctionCallbackInfo, Env, Local};

use nodejs_sys as napi;

#[repr(C)]
pub struct CCallback {
pub static_callback: *mut c_void,
Expand All @@ -17,19 +19,78 @@ impl Default for CCallback {
}
}

pub unsafe extern "C" fn set_return(_info: &FunctionCallbackInfo, _value: Local) { unimplemented!() }
pub unsafe extern "C" fn set_return(_info: FunctionCallbackInfo, _value: Local) {

}

pub unsafe extern "C" fn get_isolate(_info: &FunctionCallbackInfo) -> Env { unimplemented!() }
pub unsafe extern "C" fn get_isolate(info: FunctionCallbackInfo) -> Env { unimplemented!() }

// FIXME: Remove. This will never be implemented
pub unsafe extern "C" fn current_isolate() -> Env { panic!("current_isolate won't be implemented in n-api") }

pub unsafe extern "C" fn is_construct(_info: &FunctionCallbackInfo) -> bool { unimplemented!() }
pub unsafe extern "C" fn is_construct(_info: FunctionCallbackInfo) -> bool { unimplemented!() }

pub unsafe extern "C" fn this(_info: &FunctionCallbackInfo, _out: &mut Local) { unimplemented!() }
pub unsafe extern "C" fn this(env: Env, info: FunctionCallbackInfo, out: &mut Local) {
let status = napi::napi_get_cb_info(
env,
info,
null_mut(),
null_mut(),
out as *mut _,
null_mut(),
);
assert_eq!(status, napi::napi_status::napi_ok);
}

pub unsafe extern "C" fn data(_info: &FunctionCallbackInfo, _out: &mut Local) { unimplemented!() }
/// Mutates the `out` argument provided to refer to the associated data value of the
/// `napi_callback_info`.
pub unsafe extern "C" fn data(env: Env, info: FunctionCallbackInfo, out: &mut *mut c_void) {
let mut data = null_mut();
let status = napi::napi_get_cb_info(
env,
info,
null_mut(),
null_mut(),
null_mut(),
&mut data as *mut _,
);
if status == napi::napi_status::napi_ok {
*out = data;
}
}

/// Gets the number of arguments passed to the function.
pub unsafe extern "C" fn len(env: Env, info: FunctionCallbackInfo) -> i32 {
let mut argc = 0usize;
let status = napi::napi_get_cb_info(
env,
info,
&mut argc as *mut _,
null_mut(),
null_mut(),
null_mut(),
);
assert_eq!(status, napi::napi_status::napi_ok);
argc as i32
}

pub unsafe extern "C" fn len(_info: &FunctionCallbackInfo) -> i32 { unimplemented!() }
/// Mutates the `out` argument provided to refer to the `napi_value` of the `i`th argument
/// passed to the function.
pub unsafe extern "C" fn get(env: Env, info: FunctionCallbackInfo, i: i32, out: &mut Local) {
// TODO make this not allocate: https://github.com/neon-bindings/neon/issues/530
// Instead, we can probably get all the arguments at once in `neon` itself?
let mut args = vec![null_mut(); (i + 1) as usize];
let mut num_args = args.len();

pub unsafe extern "C" fn get(_info: &FunctionCallbackInfo, _i: i32, _out: &mut Local) { unimplemented!() }
let status = napi::napi_get_cb_info(
env,
info,
&mut num_args as *mut _,
args.as_mut_ptr(),
null_mut(),
null_mut(),
);
assert_eq!(status, napi::napi_status::napi_ok);
assert!(num_args > i as usize);
*out = args[i as usize];
}
6 changes: 3 additions & 3 deletions crates/neon-runtime/src/napi/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ pub unsafe extern "C" fn metadata_to_constructor(_out: &mut Local, _isolate: Env

// FIXME: get rid of all the "kernel" nomenclature

pub unsafe extern "C" fn get_allocate_kernel(_obj: Local) -> *mut c_void { unimplemented!() }
pub unsafe extern "C" fn get_allocate_kernel(_data: *mut c_void) -> *mut c_void { unimplemented!() }

pub unsafe extern "C" fn get_construct_kernel(_obj: Local) -> *mut c_void { unimplemented!() }
pub unsafe extern "C" fn get_construct_kernel(_data: *mut c_void) -> *mut c_void { unimplemented!() }

pub unsafe extern "C" fn get_call_kernel(_obj: Local) -> *mut c_void { unimplemented!() }
pub unsafe extern "C" fn get_call_kernel(_data: *mut c_void) -> *mut c_void { unimplemented!() }

pub unsafe extern "C" fn constructor(_out: &mut Local, _ft: Local) -> bool { unimplemented!() }

Expand Down
43 changes: 37 additions & 6 deletions crates/neon-runtime/src/napi/fun.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,44 @@
use std::os::raw::c_void;
//! Facilities for working with JS functions.
use call::CCallback;
use raw::{Env, Local};
use std::os::raw::c_void;
use std::mem::MaybeUninit;
use std::ptr::{null, null_mut};

use nodejs_sys as napi;

/// Mutates the `out` argument provided to refer to a newly created `v8::Function`. Returns
/// `false` if the value couldn't be created.
pub unsafe extern "C" fn new(out: &mut Local, env: Env, callback: CCallback) -> bool {
let status = napi::napi_create_function(
env,
null(),
0,
Some(std::mem::transmute(callback.static_callback)),
callback.dynamic_callback,
out as *mut Local,
);

status == napi::napi_status::napi_ok
}

pub unsafe extern "C" fn new_template(_out: &mut Local, _env: Env, _callback: CCallback) -> bool {
unimplemented!()
}

pub unsafe extern "C" fn new(_out: &mut Local, _env: Env, _callback: CCallback) -> bool { unimplemented!() }
pub unsafe extern "C" fn get_dynamic_callback(env: Env, data: *mut c_void) -> *mut c_void {
data
}

pub unsafe extern "C" fn new_template(_out: &mut Local, _env: Env, _callback: CCallback) -> bool { unimplemented!() }
pub unsafe extern "C" fn call(out: &mut Local, env: Env, fun: Local, this: Local, argc: i32, argv: *mut c_void) -> bool {
let status = napi::napi_call_function(env, this, fun, argc as usize, argv as *const _, out as *mut _);

pub unsafe extern "C" fn get_dynamic_callback(_obj: Local) -> *mut c_void { unimplemented!() }
status == napi::napi_status::napi_ok
}

pub unsafe extern "C" fn call(_out: &mut Local, _env: Env, _fun: Local, _this: Local, _argc: i32, _argv: *mut c_void) -> bool { unimplemented!() }
pub unsafe extern "C" fn construct(out: &mut Local, env: Env, fun: Local, argc: i32, argv: *mut c_void) -> bool {
let status = napi::napi_new_instance(env, fun, argc as usize, argv as *const _, out as *mut _);

pub unsafe extern "C" fn construct(_out: &mut Local, _env: Env, _fun: Local, _argc: i32, _argv: *mut c_void) -> bool { unimplemented!() }
status == napi::napi_status::napi_ok
}
4 changes: 2 additions & 2 deletions crates/neon-runtime/src/napi/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use std::ptr;

use nodejs_sys as napi;

pub type Local = napi::napi_value;
pub type Local = napi::napi_value;

pub type FunctionCallbackInfo = c_void;
pub type FunctionCallbackInfo = napi::napi_callback_info;

pub type Env = napi::napi_env;

Expand Down
4 changes: 3 additions & 1 deletion crates/neon-runtime/src/napi/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@ pub unsafe extern "C" fn escapable_size() -> usize { unimplemented!() }

pub unsafe extern "C" fn escapable_alignment() -> usize { unimplemented!() }

pub unsafe extern "C" fn get_global(_env: Env, _out: &mut Local) { unimplemented!() }
pub unsafe extern "C" fn get_global(env: Env, out: &mut Local) {
assert_eq!(napi::napi_get_global(env, out as *mut _), napi::napi_status::napi_ok);
}
8 changes: 6 additions & 2 deletions crates/neon-runtime/src/napi/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,15 @@ pub unsafe extern "C" fn is_string(env: Env, val: Local) -> bool {
is_type(env, val, napi::napi_valuetype::napi_string)
}

pub unsafe extern "C" fn is_object(_env: Env, _val: Local) -> bool { unimplemented!() }
pub unsafe extern "C" fn is_object(env: Env, val: Local) -> bool {
is_type(env, val, napi::napi_valuetype::napi_object)
}

pub unsafe extern "C" fn is_array(_env: Env, _val: Local) -> bool { unimplemented!() }

pub unsafe extern "C" fn is_function(_env: Env, _val: Local) -> bool { unimplemented!() }
pub unsafe extern "C" fn is_function(env: Env, val: Local) -> bool {
is_type(env, val, napi::napi_valuetype::napi_function)
}

pub unsafe extern "C" fn is_error(_env: Env, _val: Local) -> bool { unimplemented!() }

Expand Down
31 changes: 18 additions & 13 deletions crates/neon-sys/native/src/neon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,30 @@ extern "C" bool Neon_Call_IsConstruct(v8::FunctionCallbackInfo<v8::Value> *info)
return info->IsConstructCall();
}

extern "C" void Neon_Call_This(v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Object> *out) {
extern "C" void Neon_Call_This(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Object> *out) {
*out = info->This();
}

extern "C" void Neon_Call_Data(v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Value> *out) {
extern "C" void Neon_Call_Data(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info, void **out) {
/*
printf("Call_Data: v8 info = %p\n", *(void **)info);
dump((void *)info, 3);
printf("Call_Data: v8 info implicit:\n");
dump_implicit((void *)info);
*/
*out = info->Data();

// Call data is stored wrapped in a v8::External by Neon_Fun_New et al, so we need to unwrap it before handing it back to Rust.
v8::Local<v8::Value> external = info->Data();
if (external->IsExternal()) {
*out = external.As<v8::External>()->Value();
}
}

extern "C" int32_t Neon_Call_Length(v8::FunctionCallbackInfo<v8::Value> *info) {
extern "C" int32_t Neon_Call_Length(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info) {
return info->Length();
}

extern "C" void Neon_Call_Get(v8::FunctionCallbackInfo<v8::Value> *info, int32_t i, v8::Local<v8::Value> *out) {
extern "C" void Neon_Call_Get(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info, int32_t i, v8::Local<v8::Value> *out) {
*out = (*info)[i];
}

Expand Down Expand Up @@ -330,18 +335,18 @@ extern "C" void Neon_Class_SetClassMap(v8::Isolate *isolate, void *map, Neon_Dro
node::AtExit(cleanup_class_map, holder);
}

extern "C" void *Neon_Class_GetCallKernel(v8::Local<v8::External> wrapper) {
neon::ClassMetadata *metadata = static_cast<neon::ClassMetadata *>(wrapper->Value());
extern "C" void *Neon_Class_GetCallKernel(void *wrapper) {
neon::ClassMetadata *metadata = static_cast<neon::ClassMetadata *>(wrapper);
return metadata->GetCallKernel();
}

extern "C" void *Neon_Class_GetConstructKernel(v8::Local<v8::External> wrapper) {
neon::ClassMetadata *metadata = static_cast<neon::ClassMetadata *>(wrapper->Value());
extern "C" void *Neon_Class_GetConstructKernel(void *wrapper) {
neon::ClassMetadata *metadata = static_cast<neon::ClassMetadata *>(wrapper);
return metadata->GetConstructKernel();
}

extern "C" void *Neon_Class_GetAllocateKernel(v8::Local<v8::External> wrapper) {
neon::BaseClassMetadata *metadata = static_cast<neon::BaseClassMetadata *>(wrapper->Value());
extern "C" void *Neon_Class_GetAllocateKernel(void *wrapper) {
neon::BaseClassMetadata *metadata = static_cast<neon::BaseClassMetadata *>(wrapper);
return metadata->GetAllocateKernel();
}

Expand Down Expand Up @@ -433,8 +438,8 @@ extern "C" bool Neon_Fun_New(v8::Local<v8::Function> *out, v8::Isolate *isolate,
return maybe_result.ToLocal(out);
}

extern "C" void *Neon_Fun_GetDynamicCallback(v8::Local<v8::External> data) {
return data->Value();
extern "C" void *Neon_Fun_GetDynamicCallback(v8::Isolate *isolate, void *data) {
return data;
}

extern "C" bool Neon_Fun_Call(v8::Local<v8::Value> *out, v8::Isolate *isolate, v8::Local<v8::Function> fun, v8::Local<v8::Value> self, int32_t argc, v8::Local<v8::Value> argv[]) {
Expand Down
16 changes: 8 additions & 8 deletions crates/neon-sys/native/src/neon.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ extern "C" {
void *Neon_Call_GetIsolate(v8::FunctionCallbackInfo<v8::Value> *info);
void *Neon_Call_CurrentIsolate();
bool Neon_Call_IsConstruct(v8::FunctionCallbackInfo<v8::Value> *info);
void Neon_Call_This(v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Object> *out);
void Neon_Call_Data(v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Value> *out);
int32_t Neon_Call_Length(v8::FunctionCallbackInfo<v8::Value> *info);
void Neon_Call_Get(v8::FunctionCallbackInfo<v8::Value> *info, int32_t i, v8::Local<v8::Value> *out);
void Neon_Call_This(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Object> *out);
void Neon_Call_Data(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info, void **out);
int32_t Neon_Call_Length(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info);
void Neon_Call_Get(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info, int32_t i, v8::Local<v8::Value> *out);

void Neon_Primitive_Number(v8::Local<v8::Number> *out, v8::Isolate *isolate, double value);
void Neon_Primitive_Undefined(v8::Local<v8::Primitive> *out, v8::Isolate *isolate);
Expand Down Expand Up @@ -75,7 +75,7 @@ extern "C" {

bool Neon_Fun_New(v8::Local<v8::Function> *out, v8::Isolate *isolate, callback_t callback);
bool Neon_Fun_Template_New(v8::Local<v8::FunctionTemplate> *out, v8::Isolate *isolate, callback_t callback);
void *Neon_Fun_GetDynamicCallback(v8::Local<v8::External> obj);
void *Neon_Fun_GetDynamicCallback(v8::Isolate *isolate, void *obj);
bool Neon_Fun_Call(v8::Local<v8::Value> *out, v8::Isolate *isolate, v8::Local<v8::Function> fun, v8::Local<v8::Value> self, int32_t argc, v8::Local<v8::Value> argv[]);
bool Neon_Fun_Construct(v8::Local<v8::Object> *out, v8::Isolate *isolate, v8::Local<v8::Function> fun, int32_t argc, v8::Local<v8::Value> argv[]);

Expand All @@ -95,9 +95,9 @@ extern "C" {
callback_t call,
Neon_DropCallback drop);
// FIXME: get rid of all the "kernel" nomenclature
void *Neon_Class_GetCallKernel(v8::Local<v8::External> wrapper);
void *Neon_Class_GetConstructKernel(v8::Local<v8::External> wrapper);
void *Neon_Class_GetAllocateKernel(v8::Local<v8::External> wrapper);
void *Neon_Class_GetCallKernel(void *wrapper);
void *Neon_Class_GetConstructKernel(void *wrapper);
void *Neon_Class_GetAllocateKernel(void *wrapper);
bool Neon_Class_Constructor(v8::Local<v8::Function> *out, v8::Local<v8::FunctionTemplate> ft);
bool Neon_Class_HasInstance(void *metadata, v8::Local<v8::Value> v);
bool Neon_Class_SetName(v8::Isolate *isolate, void *metadata, const char *name, uint32_t byte_length);
Expand Down
24 changes: 12 additions & 12 deletions crates/neon-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct Local {
///
/// It contains the arguments used to invoke the function, the isolate reference, the `this` object
/// the function is bound to and a mechanism to return a value to the caller.
pub type FunctionCallbackInfo = c_void;
pub type FunctionCallbackInfo = *const c_void;

#[repr(C)]
#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -93,14 +93,14 @@ extern "C" {
pub fn Neon_Buffer_Uninitialized(out: &mut Local, size: u32) -> bool;
pub fn Neon_Buffer_Data<'a, 'b>(base_out: &'a mut *mut c_void, obj: Local) -> usize;

pub fn Neon_Call_SetReturn(info: &FunctionCallbackInfo, value: Local);
pub fn Neon_Call_GetIsolate(info: &FunctionCallbackInfo) -> Isolate;
pub fn Neon_Call_SetReturn(info: FunctionCallbackInfo, value: Local);
pub fn Neon_Call_GetIsolate(info: FunctionCallbackInfo) -> Isolate;
pub fn Neon_Call_CurrentIsolate() -> Isolate;
pub fn Neon_Call_IsConstruct(info: &FunctionCallbackInfo) -> bool;
pub fn Neon_Call_This(info: &FunctionCallbackInfo, out: &mut Local);
pub fn Neon_Call_Data(info: &FunctionCallbackInfo, out: &mut Local);
pub fn Neon_Call_Length(info: &FunctionCallbackInfo) -> i32;
pub fn Neon_Call_Get(info: &FunctionCallbackInfo, i: i32, out: &mut Local);
pub fn Neon_Call_IsConstruct(info: FunctionCallbackInfo) -> bool;
pub fn Neon_Call_This(isolate: Isolate, info: FunctionCallbackInfo, out: &mut Local);
pub fn Neon_Call_Data(isolate: Isolate, info: FunctionCallbackInfo, out: &mut *mut c_void);
pub fn Neon_Call_Length(isolate: Isolate, info: FunctionCallbackInfo) -> i32;
pub fn Neon_Call_Get(isolate: Isolate, info: FunctionCallbackInfo, i: i32, out: &mut Local);

pub fn Neon_Class_GetClassMap(isolate: Isolate) -> *mut c_void;
pub fn Neon_Class_SetClassMap(isolate: Isolate, map: *mut c_void, free_map: *mut c_void);
Expand All @@ -115,9 +115,9 @@ extern "C" {
pub fn Neon_Class_ThrowThisError(isolate: Isolate, metadata: *mut c_void);
pub fn Neon_Class_AddMethod(isolate: Isolate, metadata: *mut c_void, name: *const u8, byte_length: u32, method: Local) -> bool;
pub fn Neon_Class_MetadataToConstructor(out: &mut Local, isolate: Isolate, metadata: *mut c_void) -> bool;
pub fn Neon_Class_GetAllocateKernel(obj: Local) -> *mut c_void;
pub fn Neon_Class_GetConstructKernel(obj: Local) -> *mut c_void;
pub fn Neon_Class_GetCallKernel(obj: Local) -> *mut c_void;
pub fn Neon_Class_GetAllocateKernel(data: *mut c_void) -> *mut c_void;
pub fn Neon_Class_GetConstructKernel(data: *mut c_void) -> *mut c_void;
pub fn Neon_Class_GetCallKernel(data: *mut c_void) -> *mut c_void;
pub fn Neon_Class_Constructor(out: &mut Local, ft: Local) -> bool;
pub fn Neon_Class_HasInstance(metadata: *mut c_void, v: Local) -> bool;
pub fn Neon_Class_GetInstanceInternals(obj: Local) -> *mut c_void;
Expand All @@ -133,7 +133,7 @@ extern "C" {

pub fn Neon_Fun_New(out: &mut Local, isolate: Isolate, callback: CCallback) -> bool;
pub fn Neon_Fun_Template_New(out: &mut Local, isolate: Isolate, callback: CCallback) -> bool;
pub fn Neon_Fun_GetDynamicCallback(obj: Local) -> *mut c_void;
pub fn Neon_Fun_GetDynamicCallback(isolate: Isolate, data: *mut c_void) -> *mut c_void;
pub fn Neon_Fun_Call(out: &mut Local, isolate: Isolate, fun: Local, this: Local, argc: i32, argv: *mut c_void) -> bool;
pub fn Neon_Fun_Construct(out: &mut Local, isolate: Isolate, fun: Local, argc: i32, argv: *mut c_void) -> bool;

Expand Down
Loading

0 comments on commit 35c8b60

Please sign in to comment.