@@ -19,11 +19,15 @@ namespace details {
19
19
20
20
#ifdef NAPI_CPP_EXCEPTIONS
21
21
22
- #define NAPI_THROW (e ) throw e
23
-
24
22
// 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
26
24
// 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
+
27
31
#define NAPI_THROW_IF_FAILED (env, status, ...) \
28
32
if ((status) != napi_ok) throw Error::New (env);
29
33
@@ -32,19 +36,30 @@ namespace details {
32
36
33
37
#else // NAPI_CPP_EXCEPTIONS
34
38
35
- #define NAPI_THROW (e ) (e).ThrowAsJavaScriptException();
36
-
37
39
// When C++ exceptions are disabled, Errors are thrown as JavaScript exceptions,
38
40
// which are pending until the callback returns to JS. The variadic parameter
39
41
// 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
+
40
57
#define NAPI_THROW_IF_FAILED (env, status, ...) \
41
58
if ((status) != napi_ok) { \
42
59
Error::New (env).ThrowAsJavaScriptException (); \
43
60
return __VA_ARGS__; \
44
61
}
45
62
46
- // We need a _VOID version of this macro to avoid warnings resulting from
47
- // leaving the NAPI_THROW_IF_FAILED `...` argument empty.
48
63
#define NAPI_THROW_IF_FAILED_VOID (env, status ) \
49
64
if ((status) != napi_ok) { \
50
65
Error::New (env).ThrowAsJavaScriptException (); \
@@ -1312,8 +1327,8 @@ inline DataView DataView::New(napi_env env,
1312
1327
size_t byteOffset) {
1313
1328
if (byteOffset > arrayBuffer.ByteLength ()) {
1314
1329
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 () );
1317
1332
}
1318
1333
return New (env, arrayBuffer, byteOffset,
1319
1334
arrayBuffer.ByteLength () - byteOffset);
@@ -1324,8 +1339,8 @@ inline DataView DataView::New(napi_env env,
1324
1339
size_t byteOffset,
1325
1340
size_t byteLength) {
1326
1341
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 () );
1329
1344
}
1330
1345
napi_value value;
1331
1346
napi_status status = napi_create_dataview (
@@ -1451,8 +1466,7 @@ inline T DataView::ReadData(size_t byteOffset) const {
1451
1466
if (byteOffset + sizeof (T) > _length ||
1452
1467
byteOffset + sizeof (T) < byteOffset) { // overflow
1453
1468
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 );
1456
1470
}
1457
1471
1458
1472
return *reinterpret_cast <T*>(static_cast <uint8_t *>(_data) + byteOffset);
@@ -1462,9 +1476,8 @@ template <typename T>
1462
1476
inline void DataView::WriteData (size_t byteOffset, T value) const {
1463
1477
if (byteOffset + sizeof (T) > _length ||
1464
1478
byteOffset + sizeof (T) < byteOffset) { // overflow
1465
- NAPI_THROW (RangeError::New (_env,
1479
+ NAPI_THROW_VOID (RangeError::New (_env,
1466
1480
" Offset is outside the bounds of the DataView" ));
1467
- return ;
1468
1481
}
1469
1482
1470
1483
*reinterpret_cast <T*>(static_cast <uint8_t *>(_data) + byteOffset) = value;
@@ -1600,7 +1613,7 @@ inline TypedArrayOf<T>::TypedArrayOf(napi_env env,
1600
1613
: TypedArray(env, value, type, length), _data(data) {
1601
1614
if (!(type == TypedArrayTypeForPrimitiveType<T>() ||
1602
1615
(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. "
1604
1617
" (Uint8 arrays may optionally have the \" clamped\" array type.)" ));
1605
1618
}
1606
1619
}
@@ -2034,8 +2047,20 @@ inline const std::string& Error::Message() const NAPI_NOEXCEPT {
2034
2047
inline void Error::ThrowAsJavaScriptException () const {
2035
2048
HandleScope scope (_env);
2036
2049
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
+
2037
2055
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
2039
2064
}
2040
2065
}
2041
2066
0 commit comments