From 8004779d40bbc912a7c4ff5a265363a538a00a77 Mon Sep 17 00:00:00 2001 From: Anshul Goyal Date: Wed, 25 Mar 2020 17:51:14 +0530 Subject: [PATCH 01/13] Migrated error type to napi error --- .gitignore | 2 + crates/neon-runtime/src/napi/error.rs | 24 ++++++--- src/context/mod.rs | 32 +++++------ src/types/error.rs | 77 +++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index f9cc099e7..f9f878d54 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ cli/lib test/cli/lib npm-debug.log rls*.log +.idea +Cargo.lock diff --git a/crates/neon-runtime/src/napi/error.rs b/crates/neon-runtime/src/napi/error.rs index 0405983de..0c2fe0ebe 100644 --- a/crates/neon-runtime/src/napi/error.rs +++ b/crates/neon-runtime/src/napi/error.rs @@ -1,11 +1,23 @@ -use raw::Local; +use raw::{Env, Local}; -pub unsafe extern "C" fn throw(_val: Local) { unimplemented!() } +use nodejs_sys as napi; -pub unsafe extern "C" fn new_error(_out: &mut Local, _msg: Local) { unimplemented!() } +pub unsafe extern "C" fn throw(env:Env,error: Local)->bool { + let status=napi::napi_throw(env,error); + status==napi::napi_status::napi_ok +} -pub unsafe extern "C" fn new_type_error(_out: &mut Local, _msg: Local) { unimplemented!() } +pub unsafe extern "C" fn new_error(out: &mut Local,env:Env,code:Local,msg:Local)->bool { + let status=napi::napi_create_error(env,code,msg,out); + status==napi::napi_status::napi_ok +} -pub unsafe extern "C" fn new_range_error(_out: &mut Local, _msg: Local) { unimplemented!() } +pub unsafe extern "C" fn new_type_error(out: &mut Local,env:Env,code:Local,msg:Local)-> bool{ + let status=napi::napi_create_type_error(env,code,msg,out); + status==napi::napi_status::napi_ok +} -pub unsafe extern "C" fn throw_error_from_utf8(_msg: *const u8, _len: i32) { unimplemented!() } +pub unsafe extern "C" fn new_range_error(out: &mut Local,env:Env,code:Local,msg:Local)->bool { + let status=napi::napi_create_range_error(env,code,msg,out); + status==napi::napi_status::napi_ok +} diff --git a/src/context/mod.rs b/src/context/mod.rs index 2febcdaf8..eba2bbe5f 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -115,12 +115,12 @@ impl<'a> Lock<'a> { } /// An _execution context_, which provides context-sensitive access to the JavaScript engine. Most operations that interact with the engine require passing a reference to a context. -/// +/// /// A context has a lifetime `'a`, which ensures the safety of handles managed by the JS garbage collector. All handles created during the lifetime of a context are kept alive for that duration and cannot outlive the context. pub trait Context<'a>: ContextInternal<'a> { /// Lock the JavaScript engine, returning an RAII guard that keeps the lock active as long as the guard is alive. - /// + /// /// If this is not the currently active context (for example, if it was used to spawn a scoped context with `execute_scoped` or `compute_scoped`), this method will panic. fn lock(&self) -> Lock { self.check_active(); @@ -128,9 +128,9 @@ pub trait Context<'a>: ContextInternal<'a> { } /// Convenience method for locking the JavaScript engine and borrowing a single JS value's internals. - /// + /// /// # Example: - /// + /// /// ```no_run /// # use neon::prelude::*; /// # fn my_neon_function(mut cx: FunctionContext) -> JsResult { @@ -140,7 +140,7 @@ pub trait Context<'a>: ContextInternal<'a> { /// # Ok(n) /// # } /// ``` - /// + /// /// Note: the borrowed value is required to be a reference to a handle instead of a handle /// as a workaround for a [Rust compiler bug](https://github.com/rust-lang/rust/issues/29997). /// We may be able to generalize this compatibly in the future when the Rust bug is fixed, @@ -157,9 +157,9 @@ pub trait Context<'a>: ContextInternal<'a> { } /// Convenience method for locking the JavaScript engine and mutably borrowing a single JS value's internals. - /// + /// /// # Example: - /// + /// /// ```no_run /// # use neon::prelude::*; /// # fn my_neon_function(mut cx: FunctionContext) -> JsResult { @@ -171,7 +171,7 @@ pub trait Context<'a>: ContextInternal<'a> { /// # Ok(cx.undefined()) /// # } /// ``` - /// + /// /// Note: the borrowed value is required to be a reference to a handle instead of a handle /// as a workaround for a [Rust compiler bug](https://github.com/rust-lang/rust/issues/29997). /// We may be able to generalize this compatibly in the future when the Rust bug is fixed, @@ -188,9 +188,9 @@ pub trait Context<'a>: ContextInternal<'a> { } /// Executes a computation in a new memory management scope. - /// + /// /// Handles created in the new scope are kept alive only for the duration of the computation and cannot escape. - /// + /// /// This method can be useful for limiting the life of temporary values created during long-running computations, to prevent leaks. fn execute_scoped(&self, f: F) -> T where F: for<'b> FnOnce(ExecuteContext<'b>) -> T @@ -203,9 +203,9 @@ pub trait Context<'a>: ContextInternal<'a> { } /// Executes a computation in a new memory management scope and computes a single result value that outlives the computation. - /// + /// /// Handles created in the new scope are kept alive only for the duration of the computation and cannot escape, with the exception of the result value, which is rooted in the outer context. - /// + /// /// This method can be useful for limiting the life of temporary values created during long-running computations, to prevent leaks. fn compute_scoped(&self, f: F) -> JsResult<'a, V> where V: Value, @@ -237,14 +237,14 @@ pub trait Context<'a>: ContextInternal<'a> { } /// Convenience method for creating a `JsString` value. - /// + /// /// If the string exceeds the limits of the JS engine, this method panics. fn string>(&mut self, s: S) -> Handle<'a, JsString> { JsString::new(self, s) } /// Convenience method for creating a `JsString` value. - /// + /// /// If the string exceeds the limits of the JS engine, this method returns an `Err` value. fn try_string>(&mut self, s: S) -> StringResult<'a> { JsString::try_new(self, s) @@ -298,7 +298,7 @@ pub trait Context<'a>: ContextInternal<'a> { /// Throws a JS value. fn throw<'b, T: Value, U>(&mut self, v: Handle<'b, T>) -> NeonResult { unsafe { - neon_runtime::error::throw(v.to_raw()); + neon_runtime::error::throw(self.env().to_raw(),v.to_raw()); } Err(Throw) } @@ -442,7 +442,7 @@ impl<'a, 'b> ContextInternal<'a> for ComputeContext<'a, 'b> { impl<'a, 'b> Context<'a> for ComputeContext<'a, 'b> { } /// A view of the JS engine in the context of a function call. -/// +/// /// The type parameter `T` is the type of the `this`-binding. pub struct CallContext<'a, T: This> { scope: Scope<'a, raw::HandleScope>, diff --git a/src/types/error.rs b/src/types/error.rs index 8b8f3e51e..21b3001b3 100644 --- a/src/types/error.rs +++ b/src/types/error.rs @@ -36,6 +36,7 @@ impl Object for JsError { } impl JsError { /// Creates a direct instance of the [`Error`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error) class. + #[cfg(feature = "legacy-runtime")] pub fn error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { let msg = cx.string(msg.as_ref()); build(|out| unsafe { @@ -44,7 +45,23 @@ impl JsError { }) } + #[cfg(feature = "napi-runtime")] + pub fn error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { + let (ptr, len) = if let Some(small) = Utf8::from(msg.as_ref()).into_small() { + small.lower() + } else{ + return Err(Throw) + }; + build(|out| unsafe { + let mut local: raw::Local = std::mem::zeroed(); + neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); + neon_runtime::error::new_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); + true + }) + } + /// Creates an instance of the [`TypeError`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/TypeError) class. + #[cfg(feature = "legacy-runtime")] pub fn type_error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { let msg = cx.string(msg.as_ref()); build(|out| unsafe { @@ -53,7 +70,23 @@ impl JsError { }) } + #[cfg(feature = "napi-runtime")] + pub fn type_error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { + let (ptr, len) = if let Some(small) = Utf8::from(msg.as_ref()).into_small() { + small.lower() + } else{ + return Err(Throw) + }; + build(|out| unsafe { + let mut local: raw::Local = std::mem::zeroed(); + neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); + neon_runtime::error::new_type_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); + true + }) + } + /// Creates an instance of the [`RangeError`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/RangeError) class. + #[cfg(feature = "legacy-runtime")] pub fn range_error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { let msg = cx.string(msg.as_ref()); build(|out| unsafe { @@ -61,8 +94,24 @@ impl JsError { true }) } + + #[cfg(feature = "napi-runtime")] + pub fn range_error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { + let (ptr, len) = if let Some(small) = Utf8::from(msg.as_ref()).into_small() { + small.lower() + } else{ + return Err(Throw) + }; + build(|out| unsafe { + let mut local: raw::Local = std::mem::zeroed(); + neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); + neon_runtime::error::new_range_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); + true + }) + } } +#[cfg(feature = "legacy-runtime")] pub(crate) fn convert_panics NeonResult>(f: F) -> NeonResult { match catch_unwind(|| { f() }) { Ok(result) => result, @@ -82,3 +131,31 @@ pub(crate) fn convert_panics NeonResult>(f: F) } } } + + +#[cfg(feature = "napi-runtime")] +pub(crate) fn convert_panics NeonResult>(f: F) -> NeonResult { + match catch_unwind(move || { f() }) { + Ok(result) => result, + Err(panic) => { + let msg = if let Some(string) = panic.downcast_ref::() { + format!("internal error in Neon module: {}", string) + } else if let Some(str) = panic.downcast_ref::<&str>() { + format!("internal error in Neon module: {}", str) + } else { + "internal error in Neon module".to_string() + }; + println!("{}",msg); + // let (data, len) = Utf8::from(&msg[..]).truncate().lower(); + // unsafe { + // build(|out| unsafe { + // let mut local: raw::Local = std::mem::zeroed(); + // neon_runtime::string::new(&mut local, cx.env().to_raw(), data, len); + // neon_runtime::error::new_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); + // true + // }); + Err(Throw) + // } + } + } +} From 4ab5356f5281a1b533ebc0a356e1679276d691d5 Mon Sep 17 00:00:00 2001 From: Anshul Goyal Date: Wed, 25 Mar 2020 20:20:45 +0530 Subject: [PATCH 02/13] Error error during legacy runtime build --- src/context/mod.rs | 4 ++++ src/handle/mod.rs | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index eba2bbe5f..e117eb7e5 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -298,7 +298,11 @@ pub trait Context<'a>: ContextInternal<'a> { /// Throws a JS value. fn throw<'b, T: Value, U>(&mut self, v: Handle<'b, T>) -> NeonResult { unsafe { + #[cfg(feature = "napi-runtime")] neon_runtime::error::throw(self.env().to_raw(),v.to_raw()); + + #[cfg(feature = "legacy-runtime")] + neon_runtime::error::throw(v.to_raw()) } Err(Throw) } diff --git a/src/handle/mod.rs b/src/handle/mod.rs index 88aece4ba..98ae96d17 100644 --- a/src/handle/mod.rs +++ b/src/handle/mod.rs @@ -71,7 +71,7 @@ impl DowncastError { impl Display for DowncastError { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "{}", self.description()) + write!(f, "{}", self.to_string()) } } @@ -96,16 +96,16 @@ impl<'a, F: Value, T: Value> JsResultExt<'a, T> for DowncastResult<'a, F, T> { impl<'a, T: Value> Handle<'a, T> { /// Safely upcast a handle to a supertype. - /// + /// /// This method does not require an execution context because it only copies a handle. pub fn upcast>(&self) -> Handle<'a, U> { Handle::new_internal(SuperType::upcast_internal(self.value)) } /// Tests whether this value is an instance of the given type. - /// + /// /// # Example: - /// + /// /// ```no_run /// # use neon::prelude::*; /// # fn my_neon_function(mut cx: FunctionContext) -> JsResult { From 2294f55c5c58d84a456968a7874c70d7c7654d7c Mon Sep 17 00:00:00 2001 From: Anshul Goyal Date: Thu, 26 Mar 2020 02:48:13 +0530 Subject: [PATCH 03/13] Removed formating --- src/context/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index e117eb7e5..d08baf749 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -115,7 +115,6 @@ impl<'a> Lock<'a> { } /// An _execution context_, which provides context-sensitive access to the JavaScript engine. Most operations that interact with the engine require passing a reference to a context. -/// /// A context has a lifetime `'a`, which ensures the safety of handles managed by the JS garbage collector. All handles created during the lifetime of a context are kept alive for that duration and cannot outlive the context. pub trait Context<'a>: ContextInternal<'a> { From cee21d1e305fbaf1c858dadf33cb4cf2f0a4728b Mon Sep 17 00:00:00 2001 From: Anshul Goyal Date: Thu, 26 Mar 2020 03:02:12 +0530 Subject: [PATCH 04/13] Removed formating --- src/context/mod.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index d08baf749..f8d18f7d5 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -98,7 +98,7 @@ pub enum CallKind { } /// An RAII implementation of a "scoped lock" of the JS engine. When this structure is dropped (falls out of scope), the engine will be unlocked. -/// +/// /// Types of JS values that support the `Borrow` and `BorrowMut` traits can be inspected while the engine is locked by passing a reference to a `Lock` to their methods. pub struct Lock<'a> { pub(crate) ledger: RefCell, @@ -119,7 +119,7 @@ impl<'a> Lock<'a> { pub trait Context<'a>: ContextInternal<'a> { /// Lock the JavaScript engine, returning an RAII guard that keeps the lock active as long as the guard is alive. - /// + /// /// If this is not the currently active context (for example, if it was used to spawn a scoped context with `execute_scoped` or `compute_scoped`), this method will panic. fn lock(&self) -> Lock { self.check_active(); @@ -127,9 +127,9 @@ pub trait Context<'a>: ContextInternal<'a> { } /// Convenience method for locking the JavaScript engine and borrowing a single JS value's internals. - /// + /// /// # Example: - /// + /// /// ```no_run /// # use neon::prelude::*; /// # fn my_neon_function(mut cx: FunctionContext) -> JsResult { @@ -139,7 +139,7 @@ pub trait Context<'a>: ContextInternal<'a> { /// # Ok(n) /// # } /// ``` - /// + /// /// Note: the borrowed value is required to be a reference to a handle instead of a handle /// as a workaround for a [Rust compiler bug](https://github.com/rust-lang/rust/issues/29997). /// We may be able to generalize this compatibly in the future when the Rust bug is fixed, @@ -156,9 +156,9 @@ pub trait Context<'a>: ContextInternal<'a> { } /// Convenience method for locking the JavaScript engine and mutably borrowing a single JS value's internals. - /// + /// /// # Example: - /// + /// /// ```no_run /// # use neon::prelude::*; /// # fn my_neon_function(mut cx: FunctionContext) -> JsResult { @@ -170,7 +170,7 @@ pub trait Context<'a>: ContextInternal<'a> { /// # Ok(cx.undefined()) /// # } /// ``` - /// + /// /// Note: the borrowed value is required to be a reference to a handle instead of a handle /// as a workaround for a [Rust compiler bug](https://github.com/rust-lang/rust/issues/29997). /// We may be able to generalize this compatibly in the future when the Rust bug is fixed, @@ -187,9 +187,9 @@ pub trait Context<'a>: ContextInternal<'a> { } /// Executes a computation in a new memory management scope. - /// + /// /// Handles created in the new scope are kept alive only for the duration of the computation and cannot escape. - /// + /// /// This method can be useful for limiting the life of temporary values created during long-running computations, to prevent leaks. fn execute_scoped(&self, f: F) -> T where F: for<'b> FnOnce(ExecuteContext<'b>) -> T @@ -202,9 +202,9 @@ pub trait Context<'a>: ContextInternal<'a> { } /// Executes a computation in a new memory management scope and computes a single result value that outlives the computation. - /// + /// /// Handles created in the new scope are kept alive only for the duration of the computation and cannot escape, with the exception of the result value, which is rooted in the outer context. - /// + /// /// This method can be useful for limiting the life of temporary values created during long-running computations, to prevent leaks. fn compute_scoped(&self, f: F) -> JsResult<'a, V> where V: Value, @@ -236,14 +236,14 @@ pub trait Context<'a>: ContextInternal<'a> { } /// Convenience method for creating a `JsString` value. - /// + /// /// If the string exceeds the limits of the JS engine, this method panics. fn string>(&mut self, s: S) -> Handle<'a, JsString> { JsString::new(self, s) } /// Convenience method for creating a `JsString` value. - /// + /// /// If the string exceeds the limits of the JS engine, this method returns an `Err` value. fn try_string>(&mut self, s: S) -> StringResult<'a> { JsString::try_new(self, s) @@ -445,7 +445,7 @@ impl<'a, 'b> ContextInternal<'a> for ComputeContext<'a, 'b> { impl<'a, 'b> Context<'a> for ComputeContext<'a, 'b> { } /// A view of the JS engine in the context of a function call. -/// +/// /// The type parameter `T` is the type of the `this`-binding. pub struct CallContext<'a, T: This> { scope: Scope<'a, raw::HandleScope>, From 393139aa197f9b8dd20b6d6d4b054812b49851ce Mon Sep 17 00:00:00 2001 From: Anshul Goyal Date: Thu, 26 Mar 2020 03:06:39 +0530 Subject: [PATCH 05/13] REmoved more formating --- src/context/mod.rs | 3 ++- src/handle/mod.rs | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index f8d18f7d5..38224cdf9 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -98,7 +98,7 @@ pub enum CallKind { } /// An RAII implementation of a "scoped lock" of the JS engine. When this structure is dropped (falls out of scope), the engine will be unlocked. -/// +/// /// Types of JS values that support the `Borrow` and `BorrowMut` traits can be inspected while the engine is locked by passing a reference to a `Lock` to their methods. pub struct Lock<'a> { pub(crate) ledger: RefCell, @@ -115,6 +115,7 @@ impl<'a> Lock<'a> { } /// An _execution context_, which provides context-sensitive access to the JavaScript engine. Most operations that interact with the engine require passing a reference to a context. +/// /// A context has a lifetime `'a`, which ensures the safety of handles managed by the JS garbage collector. All handles created during the lifetime of a context are kept alive for that duration and cannot outlive the context. pub trait Context<'a>: ContextInternal<'a> { diff --git a/src/handle/mod.rs b/src/handle/mod.rs index 98ae96d17..6855c4c02 100644 --- a/src/handle/mod.rs +++ b/src/handle/mod.rs @@ -96,16 +96,16 @@ impl<'a, F: Value, T: Value> JsResultExt<'a, T> for DowncastResult<'a, F, T> { impl<'a, T: Value> Handle<'a, T> { /// Safely upcast a handle to a supertype. - /// + /// /// This method does not require an execution context because it only copies a handle. pub fn upcast>(&self) -> Handle<'a, U> { Handle::new_internal(SuperType::upcast_internal(self.value)) } /// Tests whether this value is an instance of the given type. - /// + /// /// # Example: - /// + /// /// ```no_run /// # use neon::prelude::*; /// # fn my_neon_function(mut cx: FunctionContext) -> JsResult { From d710798ffa5135e8da0c78ac37d1320f43f93395 Mon Sep 17 00:00:00 2001 From: Anshul Goyal Date: Thu, 26 Mar 2020 21:20:02 +0530 Subject: [PATCH 06/13] added cfg to function bodies --- .gitignore | 2 - crates/neon-runtime/src/napi/error.rs | 9 +-- src/types/error.rs | 85 +++++++++++++++------------ 3 files changed, 51 insertions(+), 45 deletions(-) diff --git a/.gitignore b/.gitignore index f9f878d54..f9cc099e7 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,3 @@ cli/lib test/cli/lib npm-debug.log rls*.log -.idea -Cargo.lock diff --git a/crates/neon-runtime/src/napi/error.rs b/crates/neon-runtime/src/napi/error.rs index 0c2fe0ebe..8abacb4a4 100644 --- a/crates/neon-runtime/src/napi/error.rs +++ b/crates/neon-runtime/src/napi/error.rs @@ -2,22 +2,23 @@ use raw::{Env, Local}; use nodejs_sys as napi; -pub unsafe extern "C" fn throw(env:Env,error: Local)->bool { +pub unsafe extern "C" fn throw(env:Env, error: Local)->bool { let status=napi::napi_throw(env,error); + assert_eq!(status, napi::napi_status::napi_ok); status==napi::napi_status::napi_ok } -pub unsafe extern "C" fn new_error(out: &mut Local,env:Env,code:Local,msg:Local)->bool { +pub unsafe extern "C" fn new_error(out: &mut Local, env:Env, code:Local, msg:Local)->bool { let status=napi::napi_create_error(env,code,msg,out); status==napi::napi_status::napi_ok } -pub unsafe extern "C" fn new_type_error(out: &mut Local,env:Env,code:Local,msg:Local)-> bool{ +pub unsafe extern "C" fn new_type_error(out: &mut Local, env:Env, code:Local, msg:Local)-> bool{ let status=napi::napi_create_type_error(env,code,msg,out); status==napi::napi_status::napi_ok } -pub unsafe extern "C" fn new_range_error(out: &mut Local,env:Env,code:Local,msg:Local)->bool { +pub unsafe extern "C" fn new_range_error(out: &mut Local, env:Env, code:Local, msg:Local)->bool { let status=napi::napi_create_range_error(env,code,msg,out); status==napi::napi_status::napi_ok } diff --git a/src/types/error.rs b/src/types/error.rs index 21b3001b3..5ceda7f50 100644 --- a/src/types/error.rs +++ b/src/types/error.rs @@ -11,6 +11,7 @@ use types::{Value, Object, Handle, Managed, build}; use types::internal::ValueInternal; use types::utf8::Utf8; + /// A JS `Error` object. #[repr(C)] #[derive(Clone, Copy)] @@ -47,70 +48,76 @@ impl JsError { #[cfg(feature = "napi-runtime")] pub fn error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { + #[cfg(feature = "legacy-runtime")] + let msg = cx.string(msg.as_ref()); + + #[cfg(feature = "napi-runtime")] let (ptr, len) = if let Some(small) = Utf8::from(msg.as_ref()).into_small() { - small.lower() - } else{ - return Err(Throw) - }; - build(|out| unsafe { - let mut local: raw::Local = std::mem::zeroed(); - neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); - neon_runtime::error::new_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); - true + small.lower() + } else{ + return Err(Throw) + }; + build(|out| unsafe { + #[cfg(feature = "napi-runtime")] + let mut local: raw::Local = std::mem::zeroed(); + #[cfg(feature = "napi-runtime")] + neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); + #[cfg(feature = "napi-runtime")] + neon_runtime::error::new_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); + #[cfg(feature = "legacy-runtime")] + neon_runtime::error::new_error(out, msg.to_raw()); + true }) } /// Creates an instance of the [`TypeError`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/TypeError) class. - #[cfg(feature = "legacy-runtime")] pub fn type_error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { - let msg = cx.string(msg.as_ref()); - build(|out| unsafe { - neon_runtime::error::new_type_error(out, msg.to_raw()); - true - }) - } + #[cfg(feature = "legacy-runtime")] + let msg = cx.string(msg.as_ref()); - #[cfg(feature = "napi-runtime")] - pub fn type_error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { - let (ptr, len) = if let Some(small) = Utf8::from(msg.as_ref()).into_small() { + #[cfg(feature = "napi-runtime")] + let (ptr, len) = if let Some(small) = Utf8::from(msg.as_ref()).into_small() { small.lower() } else{ return Err(Throw) }; - build(|out| unsafe { + build(|out| unsafe { + #[cfg(feature = "napi-runtime")] let mut local: raw::Local = std::mem::zeroed(); + #[cfg(feature = "napi-runtime")] neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); + #[cfg(feature = "napi-runtime")] neon_runtime::error::new_type_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); + #[cfg(feature = "legacy-runtime")] + neon_runtime::error::new_type_error(out, msg.to_raw()); true - }) + }) } /// Creates an instance of the [`RangeError`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/RangeError) class. - #[cfg(feature = "legacy-runtime")] pub fn range_error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { + #[cfg(feature = "legacy-runtime")] let msg = cx.string(msg.as_ref()); - build(|out| unsafe { - neon_runtime::error::new_range_error(out, msg.to_raw()); - true - }) - } - #[cfg(feature = "napi-runtime")] - pub fn range_error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { + #[cfg(feature = "napi-runtime")] let (ptr, len) = if let Some(small) = Utf8::from(msg.as_ref()).into_small() { - small.lower() - } else{ - return Err(Throw) - }; - build(|out| unsafe { - let mut local: raw::Local = std::mem::zeroed(); - neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); - neon_runtime::error::new_range_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); - true + small.lower() + } else{ + return Err(Throw) + }; + build(|out| unsafe { + #[cfg(feature = "napi-runtime")] + let mut local: raw::Local = std::mem::zeroed(); + #[cfg(feature = "napi-runtime")] + neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); + #[cfg(feature = "napi-runtime")] + neon_runtime::error::new_range_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); + #[cfg(feature = "legacy-runtime")] + neon_runtime::error::new_range_error(out, msg.to_raw()); + true }) } } - #[cfg(feature = "legacy-runtime")] pub(crate) fn convert_panics NeonResult>(f: F) -> NeonResult { match catch_unwind(|| { f() }) { From d18c514b4d06b0686f32d49d3deab16c949c1e12 Mon Sep 17 00:00:00 2001 From: Anshul Goyal Date: Fri, 27 Mar 2020 02:50:15 +0530 Subject: [PATCH 07/13] Fixed error --- src/types/error.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/types/error.rs b/src/types/error.rs index 5ceda7f50..7e1af52ea 100644 --- a/src/types/error.rs +++ b/src/types/error.rs @@ -37,16 +37,6 @@ impl Object for JsError { } impl JsError { /// Creates a direct instance of the [`Error`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error) class. - #[cfg(feature = "legacy-runtime")] - pub fn error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { - let msg = cx.string(msg.as_ref()); - build(|out| unsafe { - neon_runtime::error::new_error(out, msg.to_raw()); - true - }) - } - - #[cfg(feature = "napi-runtime")] pub fn error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { #[cfg(feature = "legacy-runtime")] let msg = cx.string(msg.as_ref()); From 126eaf8fe9890931a75d49f39f5307c3237d17fb Mon Sep 17 00:00:00 2001 From: Anshul Goyal Date: Sat, 18 Apr 2020 18:23:19 +0530 Subject: [PATCH 08/13] Fixed panic hook --- src/object/class/internal.rs | 30 +++++++ src/types/error.rs | 155 +++++++++++++++++++++-------------- src/types/internal.rs | 5 ++ 3 files changed, 128 insertions(+), 62 deletions(-) diff --git a/src/object/class/internal.rs b/src/object/class/internal.rs index c707169cc..40d73c526 100644 --- a/src/object/class/internal.rs +++ b/src/object/class/internal.rs @@ -28,6 +28,11 @@ impl Callback<()> for MethodCallback { }; let dynamic_callback: fn(CallContext) -> JsResult = mem::transmute(neon_runtime::fun::get_dynamic_callback(data.to_raw())); + #[cfg(feature = "napi-runtime")] + if let Ok(value) = convert_panics(cx,|cx| { dynamic_callback(cx) }) { + info.set_return(value); + } + #[cfg(feature = "legacy-runtime")] if let Ok(value) = convert_panics(|| { dynamic_callback(cx) }) { info.set_return(value); } @@ -65,9 +70,15 @@ impl Callback<()> for ConstructorCallCallback { let data = info.data(); let kernel: fn(CallContext) -> JsResult = mem::transmute(neon_runtime::class::get_call_kernel(data.to_raw())); + #[cfg(feature = "napi-runtime")] + if let Ok(value) = convert_panics(cx,|cx| { kernel(cx) }) { + info.set_return(value); + } + #[cfg(feature = "legacy-runtime")] if let Ok(value) = convert_panics(|| { kernel(cx) }) { info.set_return(value); } + }) } } @@ -87,6 +98,15 @@ impl Callback<*mut c_void> for AllocateCallback { let data = info.data(); let kernel: fn(CallContext) -> NeonResult = mem::transmute(neon_runtime::class::get_allocate_kernel(data.to_raw())); + #[cfg(feature = "napi-runtime")] + if let Ok(value) = convert_panics(cx,|cx| { kernel(cx) }) { + let p = Box::into_raw(Box::new(value)); + mem::transmute(p) + } else { + null_mut() + } + + #[cfg(feature = "legacy-runtime")] if let Ok(value) = convert_panics(|| { kernel(cx) }) { let p = Box::into_raw(Box::new(value)); mem::transmute(p) @@ -112,6 +132,16 @@ impl Callback for ConstructCallback { let data = info.data(); let kernel: fn(CallContext) -> NeonResult>> = mem::transmute(neon_runtime::class::get_construct_kernel(data.to_raw())); + #[cfg(feature = "napi-runtime")] + match convert_panics(cx,|cx| { kernel(cx) }) { + Ok(None) => true, + Ok(Some(obj)) => { + info.set_return(obj); + true + } + _ => false + } + #[cfg(feature = "legacy-runtime")] match convert_panics(|| { kernel(cx) }) { Ok(None) => true, Ok(Some(obj)) => { diff --git a/src/types/error.rs b/src/types/error.rs index 7e1af52ea..a4fe687ac 100644 --- a/src/types/error.rs +++ b/src/types/error.rs @@ -1,16 +1,15 @@ //! Types and traits representing JavaScript error values. -use std::panic::{UnwindSafe, catch_unwind}; +use std::panic::{catch_unwind, UnwindSafe}; use neon_runtime; use neon_runtime::raw; use context::Context; use result::{NeonResult, Throw}; -use types::{Value, Object, Handle, Managed, build}; use types::internal::ValueInternal; use types::utf8::Utf8; - +use types::{build, Handle, Managed, Object, Value}; /// A JS `Error` object. #[repr(C)] @@ -18,99 +17,124 @@ use types::utf8::Utf8; pub struct JsError(raw::Local); impl Managed for JsError { - fn to_raw(self) -> raw::Local { self.0 } + fn to_raw(self) -> raw::Local { + self.0 + } - fn from_raw(h: raw::Local) -> Self { JsError(h) } + fn from_raw(h: raw::Local) -> Self { + JsError(h) + } } impl ValueInternal for JsError { - fn name() -> String { "Error".to_string() } + fn name() -> String { + "Error".to_string() + } fn is_typeof(other: Other) -> bool { unsafe { neon_runtime::tag::is_error(other.to_raw()) } } } -impl Value for JsError { } +impl Value for JsError {} -impl Object for JsError { } +impl Object for JsError {} impl JsError { /// Creates a direct instance of the [`Error`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error) class. - pub fn error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { + pub fn error<'a, C: Context<'a>, S: AsRef>( + cx: &mut C, + msg: S, + ) -> NeonResult> { #[cfg(feature = "legacy-runtime")] let msg = cx.string(msg.as_ref()); #[cfg(feature = "napi-runtime")] let (ptr, len) = if let Some(small) = Utf8::from(msg.as_ref()).into_small() { - small.lower() - } else{ - return Err(Throw) - }; - build(|out| unsafe { - #[cfg(feature = "napi-runtime")] - let mut local: raw::Local = std::mem::zeroed(); - #[cfg(feature = "napi-runtime")] - neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); - #[cfg(feature = "napi-runtime")] - neon_runtime::error::new_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); - #[cfg(feature = "legacy-runtime")] - neon_runtime::error::new_error(out, msg.to_raw()); - true + small.lower() + } else { + return Err(Throw); + }; + build(|out| unsafe { + #[cfg(feature = "napi-runtime")] + let mut local: raw::Local = std::mem::zeroed(); + #[cfg(feature = "napi-runtime")] + neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); + #[cfg(feature = "napi-runtime")] + neon_runtime::error::new_error(out, cx.env().to_raw(), std::ptr::null_mut(), local); + #[cfg(feature = "legacy-runtime")] + neon_runtime::error::new_error(out, msg.to_raw()); + true }) } /// Creates an instance of the [`TypeError`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/TypeError) class. - pub fn type_error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { + pub fn type_error<'a, C: Context<'a>, S: AsRef>( + cx: &mut C, + msg: S, + ) -> NeonResult> { #[cfg(feature = "legacy-runtime")] - let msg = cx.string(msg.as_ref()); + let msg = cx.string(msg.as_ref()); - #[cfg(feature = "napi-runtime")] - let (ptr, len) = if let Some(small) = Utf8::from(msg.as_ref()).into_small() { + #[cfg(feature = "napi-runtime")] + let (ptr, len) = if let Some(small) = Utf8::from(msg.as_ref()).into_small() { small.lower() - } else{ - return Err(Throw) + } else { + return Err(Throw); }; - build(|out| unsafe { + build(|out| unsafe { #[cfg(feature = "napi-runtime")] let mut local: raw::Local = std::mem::zeroed(); #[cfg(feature = "napi-runtime")] neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); #[cfg(feature = "napi-runtime")] - neon_runtime::error::new_type_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); + neon_runtime::error::new_type_error( + out, + cx.env().to_raw(), + std::ptr::null_mut(), + local, + ); #[cfg(feature = "legacy-runtime")] neon_runtime::error::new_type_error(out, msg.to_raw()); true - }) + }) } /// Creates an instance of the [`RangeError`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/RangeError) class. - pub fn range_error<'a, C: Context<'a>, S: AsRef>(cx: &mut C, msg: S) -> NeonResult> { + pub fn range_error<'a, C: Context<'a>, S: AsRef>( + cx: &mut C, + msg: S, + ) -> NeonResult> { #[cfg(feature = "legacy-runtime")] let msg = cx.string(msg.as_ref()); #[cfg(feature = "napi-runtime")] let (ptr, len) = if let Some(small) = Utf8::from(msg.as_ref()).into_small() { - small.lower() - } else{ - return Err(Throw) - }; - build(|out| unsafe { - #[cfg(feature = "napi-runtime")] - let mut local: raw::Local = std::mem::zeroed(); - #[cfg(feature = "napi-runtime")] - neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); - #[cfg(feature = "napi-runtime")] - neon_runtime::error::new_range_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); - #[cfg(feature = "legacy-runtime")] - neon_runtime::error::new_range_error(out, msg.to_raw()); - true + small.lower() + } else { + return Err(Throw); + }; + build(|out| unsafe { + #[cfg(feature = "napi-runtime")] + let mut local: raw::Local = std::mem::zeroed(); + #[cfg(feature = "napi-runtime")] + neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); + #[cfg(feature = "napi-runtime")] + neon_runtime::error::new_range_error( + out, + cx.env().to_raw(), + std::ptr::null_mut(), + local, + ); + #[cfg(feature = "legacy-runtime")] + neon_runtime::error::new_range_error(out, msg.to_raw()); + true }) } } #[cfg(feature = "legacy-runtime")] pub(crate) fn convert_panics NeonResult>(f: F) -> NeonResult { - match catch_unwind(|| { f() }) { + match catch_unwind(|| f()) { Ok(result) => result, Err(panic) => { let msg = if let Some(string) = panic.downcast_ref::() { @@ -129,10 +153,18 @@ pub(crate) fn convert_panics NeonResult>(f: F) } } - #[cfg(feature = "napi-runtime")] -pub(crate) fn convert_panics NeonResult>(f: F) -> NeonResult { - match catch_unwind(move || { f() }) { +pub(crate) fn convert_panics< + 'a, + T, + C: Context<'a> + std::panic::UnwindSafe, + F: UnwindSafe + FnOnce(C) -> NeonResult, +>( + cx: C, + f: F, +) -> NeonResult { + let env = cx.env().to_raw(); + match catch_unwind(move || f(cx)) { Ok(result) => result, Err(panic) => { let msg = if let Some(string) = panic.downcast_ref::() { @@ -142,17 +174,16 @@ pub(crate) fn convert_panics NeonResult>(f: F) } else { "internal error in Neon module".to_string() }; - println!("{}",msg); - // let (data, len) = Utf8::from(&msg[..]).truncate().lower(); - // unsafe { - // build(|out| unsafe { - // let mut local: raw::Local = std::mem::zeroed(); - // neon_runtime::string::new(&mut local, cx.env().to_raw(), data, len); - // neon_runtime::error::new_error(out,cx.env().to_raw(),std::ptr::null_mut(),local); - // true - // }); - Err(Throw) - // } + println!("{}", msg); + let (data, len) = Utf8::from(&msg[..]).truncate().lower(); + unsafe { + let mut local: raw::Local = std::mem::zeroed(); + let mut error: raw::Local = std::mem::zeroed(); + neon_runtime::string::new(&mut local, env, data, len); + neon_runtime::error::new_error(&mut error, env, std::ptr::null_mut(), local); + neon_runtime::error::throw(env,error); + }; + Err(Throw) } } } diff --git a/src/types/internal.rs b/src/types/internal.rs index 3675c1e00..952b18e3e 100644 --- a/src/types/internal.rs +++ b/src/types/internal.rs @@ -37,6 +37,11 @@ impl Callback<()> for FunctionCallback { let data = info.data(); let dynamic_callback: fn(FunctionContext) -> JsResult = mem::transmute(neon_runtime::fun::get_dynamic_callback(data.to_raw())); + #[cfg(feature = "napi-runtime")] + if let Ok(value) = convert_panics(cx,|cx| { dynamic_callback(cx) }) { + info.set_return(value); + } + #[cfg(feature = "legacy-runtime")] if let Ok(value) = convert_panics(|| { dynamic_callback(cx) }) { info.set_return(value); } From 48ef51ce4d065284c692f62dba5f409ffe095dd7 Mon Sep 17 00:00:00 2001 From: Anshul Goyal Date: Sat, 18 Apr 2020 18:56:04 +0530 Subject: [PATCH 09/13] Fixed build on stable version --- src/object/class/internal.rs | 31 +++++++++++++++---------------- src/types/internal.rs | 9 +++++---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/object/class/internal.rs b/src/object/class/internal.rs index 40d73c526..ed7b6a7e3 100644 --- a/src/object/class/internal.rs +++ b/src/object/class/internal.rs @@ -28,12 +28,14 @@ impl Callback<()> for MethodCallback { }; let dynamic_callback: fn(CallContext) -> JsResult = mem::transmute(neon_runtime::fun::get_dynamic_callback(data.to_raw())); + #[cfg(feature = "napi-runtime")] - if let Ok(value) = convert_panics(cx,|cx| { dynamic_callback(cx) }) { - info.set_return(value); - } + let result=convert_panics(cx,|cx| { dynamic_callback(cx) }); + #[cfg(feature = "legacy-runtime")] - if let Ok(value) = convert_panics(|| { dynamic_callback(cx) }) { + let result=convert_panics(|| { dynamic_callback(cx) }); + + if let Ok(value) = result { info.set_return(value); } }) @@ -71,14 +73,13 @@ impl Callback<()> for ConstructorCallCallback { let kernel: fn(CallContext) -> JsResult = mem::transmute(neon_runtime::class::get_call_kernel(data.to_raw())); #[cfg(feature = "napi-runtime")] - if let Ok(value) = convert_panics(cx,|cx| { kernel(cx) }) { - info.set_return(value); - } + let result= convert_panics(cx,|cx| { kernel(cx) }); + #[cfg(feature = "legacy-runtime")] - if let Ok(value) = convert_panics(|| { kernel(cx) }) { + let result= convert_panics(|| { kernel(cx) }); + if let Ok(value) =result { info.set_return(value); } - }) } } @@ -98,16 +99,14 @@ impl Callback<*mut c_void> for AllocateCallback { let data = info.data(); let kernel: fn(CallContext) -> NeonResult = mem::transmute(neon_runtime::class::get_allocate_kernel(data.to_raw())); + #[cfg(feature = "napi-runtime")] - if let Ok(value) = convert_panics(cx,|cx| { kernel(cx) }) { - let p = Box::into_raw(Box::new(value)); - mem::transmute(p) - } else { - null_mut() - } + let result=convert_panics(cx,|cx| { kernel(cx) }); #[cfg(feature = "legacy-runtime")] - if let Ok(value) = convert_panics(|| { kernel(cx) }) { + let result=convert_panics(|| { kernel(cx) }); + + if let Ok(value) = result { let p = Box::into_raw(Box::new(value)); mem::transmute(p) } else { diff --git a/src/types/internal.rs b/src/types/internal.rs index 952b18e3e..ce2f53ab5 100644 --- a/src/types/internal.rs +++ b/src/types/internal.rs @@ -38,11 +38,12 @@ impl Callback<()> for FunctionCallback { let dynamic_callback: fn(FunctionContext) -> JsResult = mem::transmute(neon_runtime::fun::get_dynamic_callback(data.to_raw())); #[cfg(feature = "napi-runtime")] - if let Ok(value) = convert_panics(cx,|cx| { dynamic_callback(cx) }) { - info.set_return(value); - } + let result=convert_panics(cx,|cx| { dynamic_callback(cx) }); + #[cfg(feature = "legacy-runtime")] - if let Ok(value) = convert_panics(|| { dynamic_callback(cx) }) { + let result=convert_panics(|| { dynamic_callback(cx) }); + + if let Ok(value) = result{ info.set_return(value); } }) From 4b5d4d7bea1cd950c70ca1434b1465db37fab2c4 Mon Sep 17 00:00:00 2001 From: Anshul Goyal Date: Sun, 17 May 2020 11:21:52 +0530 Subject: [PATCH 10/13] Removed duplicate code --- crates/neon-runtime/src/napi/error.rs | 15 ++-- src/object/class/internal.rs | 86 ++++++++++------------ src/types/error.rs | 101 ++++++++++++-------------- src/types/internal.rs | 21 ++---- 4 files changed, 98 insertions(+), 125 deletions(-) diff --git a/crates/neon-runtime/src/napi/error.rs b/crates/neon-runtime/src/napi/error.rs index 8abacb4a4..40cda3650 100644 --- a/crates/neon-runtime/src/napi/error.rs +++ b/crates/neon-runtime/src/napi/error.rs @@ -2,23 +2,22 @@ use raw::{Env, Local}; use nodejs_sys as napi; -pub unsafe extern "C" fn throw(env:Env, error: Local)->bool { +pub unsafe extern "C" fn throw(env:Env, error: Local){ let status=napi::napi_throw(env,error); assert_eq!(status, napi::napi_status::napi_ok); - status==napi::napi_status::napi_ok } -pub unsafe extern "C" fn new_error(out: &mut Local, env:Env, code:Local, msg:Local)->bool { +pub unsafe extern "C" fn new_error(out: &mut Local, env:Env, code:Local, msg:Local){ let status=napi::napi_create_error(env,code,msg,out); - status==napi::napi_status::napi_ok + assert_eq!(status, napi::napi_status::napi_ok); } -pub unsafe extern "C" fn new_type_error(out: &mut Local, env:Env, code:Local, msg:Local)-> bool{ +pub unsafe extern "C" fn new_type_error(out: &mut Local, env:Env, code:Local, msg:Local){ let status=napi::napi_create_type_error(env,code,msg,out); - status==napi::napi_status::napi_ok + assert_eq!(status, napi::napi_status::napi_ok); } -pub unsafe extern "C" fn new_range_error(out: &mut Local, env:Env, code:Local, msg:Local)->bool { +pub unsafe extern "C" fn new_range_error(out: &mut Local, env:Env, code:Local, msg:Local) { let status=napi::napi_create_range_error(env,code,msg,out); - status==napi::napi_status::napi_ok + assert_eq!(status, napi::napi_status::napi_ok); } diff --git a/src/object/class/internal.rs b/src/object/class/internal.rs index ed7b6a7e3..349081241 100644 --- a/src/object/class/internal.rs +++ b/src/object/class/internal.rs @@ -1,15 +1,15 @@ +use super::{Callback, Class, ClassInternal}; +use context::internal::ContextInternal; +use context::{CallContext, CallbackInfo, Context}; +use handle::{Handle, Managed}; +use neon_runtime; +use neon_runtime::raw; +use result::{JsResult, NeonResult, Throw}; use std::mem; use std::os::raw::c_void; use std::ptr::null_mut; -use neon_runtime; -use neon_runtime::raw; -use super::{Class, ClassInternal, Callback}; -use handle::{Handle, Managed}; -use context::{CallbackInfo, CallContext, Context}; -use context::internal::ContextInternal; -use result::{NeonResult, JsResult, Throw}; -use types::{JsValue, JsObject, JsFunction, JsUndefined, build}; use types::error::convert_panics; +use types::{build, JsFunction, JsObject, JsUndefined, JsValue}; #[repr(C)] pub struct MethodCallback(pub fn(CallContext) -> JsResult); @@ -19,28 +19,25 @@ impl Callback<()> for MethodCallback { unsafe { info.with_cx::(|mut cx| { let data = info.data(); - let this: Handle = Handle::new_internal(JsValue::from_raw(info.this(&mut cx))); + let this: Handle = + Handle::new_internal(JsValue::from_raw(info.this(&mut cx))); if !this.is_a::() { if let Ok(metadata) = T::metadata(&mut cx) { - neon_runtime::class::throw_this_error(mem::transmute(cx.env()), metadata.pointer); + neon_runtime::class::throw_this_error( + mem::transmute(cx.env()), + metadata.pointer, + ); } return; }; let dynamic_callback: fn(CallContext) -> JsResult = mem::transmute(neon_runtime::fun::get_dynamic_callback(data.to_raw())); - - #[cfg(feature = "napi-runtime")] - let result=convert_panics(cx,|cx| { dynamic_callback(cx) }); - - #[cfg(feature = "legacy-runtime")] - let result=convert_panics(|| { dynamic_callback(cx) }); - - if let Ok(value) = result { + if let Ok(value) = convert_panics(cx, |cx| dynamic_callback(cx)) { info.set_return(value); } }) } - } + } fn as_ptr(self) -> *mut c_void { self.0 as *mut c_void @@ -55,7 +52,10 @@ impl ConstructorCallCallback { fn callback(mut cx: CallContext) -> JsResult { unsafe { if let Ok(metadata) = T::metadata(&mut cx) { - neon_runtime::class::throw_call_error(mem::transmute(cx.env()), metadata.pointer); + neon_runtime::class::throw_call_error( + mem::transmute(cx.env()), + metadata.pointer, + ); } } Err(Throw) @@ -72,12 +72,7 @@ impl Callback<()> for ConstructorCallCallback { let data = info.data(); let kernel: fn(CallContext) -> JsResult = mem::transmute(neon_runtime::class::get_call_kernel(data.to_raw())); - #[cfg(feature = "napi-runtime")] - let result= convert_panics(cx,|cx| { kernel(cx) }); - - #[cfg(feature = "legacy-runtime")] - let result= convert_panics(|| { kernel(cx) }); - if let Ok(value) =result { + if let Ok(value) = convert_panics(cx, |cx| kernel(cx)) { info.set_return(value); } }) @@ -99,14 +94,8 @@ impl Callback<*mut c_void> for AllocateCallback { let data = info.data(); let kernel: fn(CallContext) -> NeonResult = mem::transmute(neon_runtime::class::get_allocate_kernel(data.to_raw())); - - #[cfg(feature = "napi-runtime")] - let result=convert_panics(cx,|cx| { kernel(cx) }); - #[cfg(feature = "legacy-runtime")] - let result=convert_panics(|| { kernel(cx) }); - - if let Ok(value) = result { + if let Ok(value) = convert_panics(cx, |cx| kernel(cx)) { let p = Box::into_raw(Box::new(value)); mem::transmute(p) } else { @@ -122,7 +111,9 @@ impl Callback<*mut c_void> for AllocateCallback { } #[repr(C)] -pub struct ConstructCallback(pub fn(CallContext) -> NeonResult>>); +pub struct ConstructCallback( + pub fn(CallContext) -> NeonResult>>, +); impl Callback for ConstructCallback { extern "C" fn invoke(info: &CallbackInfo) -> bool { @@ -131,23 +122,13 @@ impl Callback for ConstructCallback { let data = info.data(); let kernel: fn(CallContext) -> NeonResult>> = mem::transmute(neon_runtime::class::get_construct_kernel(data.to_raw())); - #[cfg(feature = "napi-runtime")] - match convert_panics(cx,|cx| { kernel(cx) }) { - Ok(None) => true, - Ok(Some(obj)) => { - info.set_return(obj); - true - } - _ => false - } - #[cfg(feature = "legacy-runtime")] - match convert_panics(|| { kernel(cx) }) { + match convert_panics(cx, |cx| kernel(cx)) { Ok(None) => true, Ok(Some(obj)) => { info.set_return(obj); true } - _ => false + _ => false, } }) } @@ -161,13 +142,20 @@ impl Callback for ConstructCallback { #[repr(C)] #[derive(Clone, Copy)] pub struct ClassMetadata { - pub(crate) pointer: *mut c_void + pub(crate) pointer: *mut c_void, } impl ClassMetadata { - pub unsafe fn constructor<'a, T: Class, C: Context<'a>>(&self, cx: &mut C) -> JsResult<'a, JsFunction> { + pub unsafe fn constructor<'a, T: Class, C: Context<'a>>( + &self, + cx: &mut C, + ) -> JsResult<'a, JsFunction> { build(|out| { - neon_runtime::class::metadata_to_constructor(out, mem::transmute(cx.env()), self.pointer) + neon_runtime::class::metadata_to_constructor( + out, + mem::transmute(cx.env()), + self.pointer, + ) }) } diff --git a/src/types/error.rs b/src/types/error.rs index a4fe687ac..6f2a92ccb 100644 --- a/src/types/error.rs +++ b/src/types/error.rs @@ -57,11 +57,11 @@ impl JsError { }; build(|out| unsafe { #[cfg(feature = "napi-runtime")] - let mut local: raw::Local = std::mem::zeroed(); - #[cfg(feature = "napi-runtime")] - neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); - #[cfg(feature = "napi-runtime")] - neon_runtime::error::new_error(out, cx.env().to_raw(), std::ptr::null_mut(), local); + { + let mut local: raw::Local = std::mem::zeroed(); + neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); + neon_runtime::error::new_error(out, cx.env().to_raw(), std::ptr::null_mut(), local); + } #[cfg(feature = "legacy-runtime")] neon_runtime::error::new_error(out, msg.to_raw()); true @@ -84,16 +84,16 @@ impl JsError { }; build(|out| unsafe { #[cfg(feature = "napi-runtime")] - let mut local: raw::Local = std::mem::zeroed(); - #[cfg(feature = "napi-runtime")] - neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); - #[cfg(feature = "napi-runtime")] - neon_runtime::error::new_type_error( - out, - cx.env().to_raw(), - std::ptr::null_mut(), - local, - ); + { + let mut local: raw::Local = std::mem::zeroed(); + neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); + neon_runtime::error::new_type_error( + out, + cx.env().to_raw(), + std::ptr::null_mut(), + local, + ); + } #[cfg(feature = "legacy-runtime")] neon_runtime::error::new_type_error(out, msg.to_raw()); true @@ -116,44 +116,23 @@ impl JsError { }; build(|out| unsafe { #[cfg(feature = "napi-runtime")] - let mut local: raw::Local = std::mem::zeroed(); - #[cfg(feature = "napi-runtime")] - neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); - #[cfg(feature = "napi-runtime")] - neon_runtime::error::new_range_error( - out, - cx.env().to_raw(), - std::ptr::null_mut(), - local, - ); + { + let mut local: raw::Local = std::mem::zeroed(); + neon_runtime::string::new(&mut local, cx.env().to_raw(), ptr, len); + neon_runtime::error::new_range_error( + out, + cx.env().to_raw(), + std::ptr::null_mut(), + local, + ); + } #[cfg(feature = "legacy-runtime")] neon_runtime::error::new_range_error(out, msg.to_raw()); true }) } } -#[cfg(feature = "legacy-runtime")] -pub(crate) fn convert_panics NeonResult>(f: F) -> NeonResult { - match catch_unwind(|| f()) { - Ok(result) => result, - Err(panic) => { - let msg = if let Some(string) = panic.downcast_ref::() { - format!("internal error in Neon module: {}", string) - } else if let Some(str) = panic.downcast_ref::<&str>() { - format!("internal error in Neon module: {}", str) - } else { - "internal error in Neon module".to_string() - }; - let (data, len) = Utf8::from(&msg[..]).truncate().lower(); - unsafe { - neon_runtime::error::throw_error_from_utf8(data, len); - Err(Throw) - } - } - } -} -#[cfg(feature = "napi-runtime")] pub(crate) fn convert_panics< 'a, T, @@ -163,6 +142,7 @@ pub(crate) fn convert_panics< cx: C, f: F, ) -> NeonResult { + #[cfg(feature = "napi-runtime")] let env = cx.env().to_raw(); match catch_unwind(move || f(cx)) { Ok(result) => result, @@ -175,15 +155,26 @@ pub(crate) fn convert_panics< "internal error in Neon module".to_string() }; println!("{}", msg); - let (data, len) = Utf8::from(&msg[..]).truncate().lower(); - unsafe { - let mut local: raw::Local = std::mem::zeroed(); - let mut error: raw::Local = std::mem::zeroed(); - neon_runtime::string::new(&mut local, env, data, len); - neon_runtime::error::new_error(&mut error, env, std::ptr::null_mut(), local); - neon_runtime::error::throw(env,error); - }; - Err(Throw) + #[cfg(feature = "legacy-runtime")] + { + let (data, len) = Utf8::from(&msg[..]).truncate().lower(); + unsafe { + neon_runtime::error::throw_error_from_utf8(data, len); + Err(Throw) + } + } + #[cfg(feature = "napi-runtime")] + { + let (data, len) = Utf8::from(&msg[..]).truncate().lower(); + unsafe { + let mut local: raw::Local = std::mem::zeroed(); + let mut error: raw::Local = std::mem::zeroed(); + neon_runtime::string::new(&mut local, env, data, len); + neon_runtime::error::new_error(&mut error, env, std::ptr::null_mut(), local); + neon_runtime::error::throw(env, error); + }; + Err(Throw) + } } } } diff --git a/src/types/internal.rs b/src/types/internal.rs index ce2f53ab5..d041cf1cd 100644 --- a/src/types/internal.rs +++ b/src/types/internal.rs @@ -1,13 +1,13 @@ -use std::mem; -use std::os::raw::c_void; +use super::Value; +use context::{CallbackInfo, FunctionContext}; use neon_runtime; use neon_runtime::raw; -use context::{CallbackInfo, FunctionContext}; -use types::error::convert_panics; -use types::{JsObject, Handle, Managed}; -use result::JsResult; use object::class::Callback; -use super::Value; +use result::JsResult; +use std::mem; +use std::os::raw::c_void; +use types::error::convert_panics; +use types::{Handle, JsObject, Managed}; pub trait ValueInternal: Managed + 'static { fn name() -> String; @@ -37,13 +37,8 @@ impl Callback<()> for FunctionCallback { let data = info.data(); let dynamic_callback: fn(FunctionContext) -> JsResult = mem::transmute(neon_runtime::fun::get_dynamic_callback(data.to_raw())); - #[cfg(feature = "napi-runtime")] - let result=convert_panics(cx,|cx| { dynamic_callback(cx) }); - - #[cfg(feature = "legacy-runtime")] - let result=convert_panics(|| { dynamic_callback(cx) }); - if let Ok(value) = result{ + if let Ok(value) = convert_panics(cx, |cx| dynamic_callback(cx)) { info.set_return(value); } }) From 6d654ec531043fe4b54b01fd8284dfc285be3bca Mon Sep 17 00:00:00 2001 From: Anshul Goyal Date: Sun, 17 May 2020 11:25:35 +0530 Subject: [PATCH 11/13] formatting fix --- crates/neon-runtime/src/napi/error.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/neon-runtime/src/napi/error.rs b/crates/neon-runtime/src/napi/error.rs index 40cda3650..bcfd8323a 100644 --- a/crates/neon-runtime/src/napi/error.rs +++ b/crates/neon-runtime/src/napi/error.rs @@ -2,22 +2,22 @@ use raw::{Env, Local}; use nodejs_sys as napi; -pub unsafe extern "C" fn throw(env:Env, error: Local){ - let status=napi::napi_throw(env,error); +pub unsafe extern "C" fn throw(env: Env, error: Local) { + let status = napi::napi_throw(env, error); assert_eq!(status, napi::napi_status::napi_ok); } -pub unsafe extern "C" fn new_error(out: &mut Local, env:Env, code:Local, msg:Local){ - let status=napi::napi_create_error(env,code,msg,out); +pub unsafe extern "C" fn new_error(out: &mut Local, env: Env, code: Local, msg: Local) { + let status = napi::napi_create_error(env, code, msg, out); assert_eq!(status, napi::napi_status::napi_ok); } -pub unsafe extern "C" fn new_type_error(out: &mut Local, env:Env, code:Local, msg:Local){ - let status=napi::napi_create_type_error(env,code,msg,out); +pub unsafe extern "C" fn new_type_error(out: &mut Local, env: Env, code: Local, msg: Local) { + let status = napi::napi_create_type_error(env, code, msg, out); assert_eq!(status, napi::napi_status::napi_ok); } -pub unsafe extern "C" fn new_range_error(out: &mut Local, env:Env, code:Local, msg:Local) { - let status=napi::napi_create_range_error(env,code,msg,out); +pub unsafe extern "C" fn new_range_error(out: &mut Local, env: Env, code: Local, msg: Local) { + let status = napi::napi_create_range_error(env, code, msg, out); assert_eq!(status, napi::napi_status::napi_ok); } From bf74b25878a85397edefe11d6ac5cd7f2681794d Mon Sep 17 00:00:00 2001 From: Anshul Goyal <32068075+anshulrgoyal@users.noreply.github.com> Date: Sun, 31 May 2020 18:11:48 +0530 Subject: [PATCH 12/13] Update internal.rs --- src/types/internal.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/types/internal.rs b/src/types/internal.rs index d041cf1cd..45b907054 100644 --- a/src/types/internal.rs +++ b/src/types/internal.rs @@ -44,7 +44,6 @@ impl Callback<()> for FunctionCallback { }) } } - fn as_ptr(self) -> *mut c_void { unsafe { mem::transmute(self.0) } } From cabb576a8e9c1fe70f08626d0b3bb43a1ff22849 Mon Sep 17 00:00:00 2001 From: Anshul Goyal Date: Sun, 31 May 2020 18:51:52 +0530 Subject: [PATCH 13/13] Fixed double import --- src/types/internal.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/types/internal.rs b/src/types/internal.rs index 05bcc5f30..979536d61 100644 --- a/src/types/internal.rs +++ b/src/types/internal.rs @@ -2,16 +2,12 @@ use super::Value; use context::{CallbackInfo, FunctionContext}; use neon_runtime; use neon_runtime::raw; -use context::{CallbackInfo, FunctionContext}; use context::internal::Env; use types::error::convert_panics; -use types::{JsObject, Handle, Managed}; -use result::JsResult; use object::class::Callback; use result::JsResult; use std::mem; use std::os::raw::c_void; -use types::error::convert_panics; use types::{Handle, JsObject, Managed}; pub trait ValueInternal: Managed + 'static {