@@ -19,11 +19,15 @@ namespace details {
1919
2020#ifdef  NAPI_CPP_EXCEPTIONS
2121
22- #define  NAPI_THROW (e )  throw  e
23- 
2422//  When C++ exceptions are enabled, Errors are thrown directly. There is no need
25- //  to return anything after the throw statement . The variadic parameter is an
23+ //  to return anything after the throw statements . The variadic parameter is an
2624//  optional return value that is ignored.
25+ //  We need _VOID versions of the macros to avoid warnings resulting from
26+ //  leaving the NAPI_THROW_* `...` argument empty.
27+ 
28+ #define  NAPI_THROW (e, ...)  throw  e
29+ #define  NAPI_THROW_VOID (e )  throw  e
30+ 
2731#define  NAPI_THROW_IF_FAILED (env, status, ...)           \
2832  if  ((status) != napi_ok) throw  Error::New (env);
2933
@@ -32,19 +36,30 @@ namespace details {
3236
3337#else  //  NAPI_CPP_EXCEPTIONS
3438
35- #define  NAPI_THROW (e )  (e).ThrowAsJavaScriptException();
36- 
3739//  When C++ exceptions are disabled, Errors are thrown as JavaScript exceptions,
3840//  which are pending until the callback returns to JS.  The variadic parameter
3941//  is an optional return value; usually it is an empty result.
42+ //  We need _VOID versions of the macros to avoid warnings resulting from
43+ //  leaving the NAPI_THROW_* `...` argument empty.
44+ 
45+ #define  NAPI_THROW (e, ...)                               \
46+   do  {                                                   \
47+     (e).ThrowAsJavaScriptException ();                    \
48+     return  __VA_ARGS__;                                  \
49+   } while  (0 )
50+ 
51+ #define  NAPI_THROW_VOID (e )                               \
52+   do  {                                                   \
53+     (e).ThrowAsJavaScriptException ();                    \
54+     return ;                                              \
55+   } while  (0 )
56+ 
4057#define  NAPI_THROW_IF_FAILED (env, status, ...)           \
4158  if  ((status) != napi_ok) {                             \
4259    Error::New (env).ThrowAsJavaScriptException ();        \
4360    return  __VA_ARGS__;                                  \
4461  }
4562
46- //  We need a _VOID version of this macro to avoid warnings resulting from
47- //  leaving the NAPI_THROW_IF_FAILED `...` argument empty.
4863#define  NAPI_THROW_IF_FAILED_VOID (env, status )           \
4964  if  ((status) != napi_ok) {                             \
5065    Error::New (env).ThrowAsJavaScriptException ();        \
@@ -1312,8 +1327,8 @@ inline DataView DataView::New(napi_env env,
13121327                              size_t  byteOffset) {
13131328  if  (byteOffset > arrayBuffer.ByteLength ()) {
13141329    NAPI_THROW (RangeError::New (env,
1315-         " Start offset is outside the bounds of the buffer" ); 
1316-     return   DataView ();
1330+         " Start offset is outside the bounds of the buffer" , 
1331+          DataView () );
13171332  }
13181333  return  New (env, arrayBuffer, byteOffset,
13191334      arrayBuffer.ByteLength () - byteOffset);
@@ -1324,8 +1339,8 @@ inline DataView DataView::New(napi_env env,
13241339                              size_t  byteOffset,
13251340                              size_t  byteLength) {
13261341  if  (byteOffset + byteLength > arrayBuffer.ByteLength ()) {
1327-     NAPI_THROW (RangeError::New (env, " Invalid DataView length" ); 
1328-     return   DataView ();
1342+     NAPI_THROW (RangeError::New (env, " Invalid DataView length" , 
1343+                 DataView () );
13291344  }
13301345  napi_value value;
13311346  napi_status status = napi_create_dataview (
@@ -1451,8 +1466,7 @@ inline T DataView::ReadData(size_t byteOffset) const {
14511466  if  (byteOffset + sizeof (T) > _length ||
14521467      byteOffset + sizeof (T) < byteOffset) {  //  overflow
14531468    NAPI_THROW (RangeError::New (_env,
1454-         " Offset is outside the bounds of the DataView" 
1455-     return  0 ;
1469+         " Offset is outside the bounds of the DataView" 0 );
14561470  }
14571471
14581472  return  *reinterpret_cast <T*>(static_cast <uint8_t *>(_data) + byteOffset);
@@ -1462,9 +1476,8 @@ template <typename T>
14621476inline  void  DataView::WriteData (size_t  byteOffset, T value) const  {
14631477  if  (byteOffset + sizeof (T) > _length ||
14641478      byteOffset + sizeof (T) < byteOffset) {  //  overflow
1465-     NAPI_THROW (RangeError::New (_env,
1479+     NAPI_THROW_VOID (RangeError::New (_env,
14661480        " Offset is outside the bounds of the DataView" 
1467-     return ;
14681481  }
14691482
14701483  *reinterpret_cast <T*>(static_cast <uint8_t *>(_data) + byteOffset) = value;
@@ -1600,7 +1613,7 @@ inline TypedArrayOf<T>::TypedArrayOf(napi_env env,
16001613  : TypedArray(env, value, type, length), _data(data) {
16011614  if  (!(type == TypedArrayTypeForPrimitiveType<T>() ||
16021615      (type == napi_uint8_clamped_array && std::is_same<T, uint8_t >::value))) {
1603-     NAPI_THROW (TypeError::New (env, " Array type must match the template parameter. " 
1616+     NAPI_THROW_VOID (TypeError::New (env, " Array type must match the template parameter. " 
16041617      " (Uint8 arrays may optionally have the \" clamped\"  array type.)" 
16051618  }
16061619}
@@ -2034,8 +2047,20 @@ inline const std::string& Error::Message() const NAPI_NOEXCEPT {
20342047inline  void  Error::ThrowAsJavaScriptException () const  {
20352048  HandleScope scope (_env);
20362049  if  (!IsEmpty ()) {
2050+ 
2051+     //  We intentionally don't use `NAPI_THROW_*` macros here to ensure
2052+     //  that there is no possible recursion as `ThrowAsJavaScriptException`
2053+     //  is part of `NAPI_THROW_*` macro definition for noexcept.
2054+ 
20372055    napi_status status = napi_throw (_env, Value ());
2038-     NAPI_THROW_IF_FAILED_VOID (_env, status);
2056+ 
2057+ #ifdef  NAPI_CPP_EXCEPTIONS
2058+     if  (status != napi_ok) {
2059+       throw  Error::New (_env);
2060+     }
2061+ #else  //  NAPI_CPP_EXCEPTIONS
2062+     NAPI_FATAL_IF_FAILED (status, " Error::ThrowAsJavaScriptException" " napi_throw" 
2063+ #endif  //  NAPI_CPP_EXCEPTIONS
20392064  }
20402065}
20412066
0 commit comments