@@ -62,14 +62,14 @@ void napi_env__::InvokeFinalizerFromGC(v8impl::RefTracker* finalizer) {
62
62
EnqueueFinalizer (finalizer);
63
63
} else {
64
64
// The experimental code calls finalizers immediately to release native
65
- // objects as soon as possible, but it suspends use of JS from finalizer.
66
- // If JS calls are needed, then the finalizer code must call
67
- // node_api_post_finalizer.
65
+ // objects as soon as possible. In that state any code that may affect GC
66
+ // state causes a fatal error. To work around this issue the finalizer code
67
+ // must call node_api_post_finalizer.
68
68
if (last_error.error_code == napi_ok && last_exception.IsEmpty ()) {
69
- bool saved_suspend_call_into_js = suspend_call_into_js;
70
- suspend_call_into_js = true ;
69
+ auto restore_state = node::OnScopeLeave (
70
+ [this , saved = in_gc_finalizer] { in_gc_finalizer = saved; });
71
+ in_gc_finalizer = true ;
71
72
finalizer->Finalize ();
72
- suspend_call_into_js = saved_suspend_call_into_js;
73
73
} else {
74
74
// The finalizers can be run in the middle of JS or C++ code.
75
75
// That code may be in an error state. In that case use the asynchronous
@@ -93,6 +93,7 @@ napi_status NewString(napi_env env,
93
93
CHECK_ARG (env, result);
94
94
RETURN_STATUS_IF_FALSE (
95
95
env, (length == NAPI_AUTO_LENGTH) || length <= INT_MAX, napi_invalid_arg);
96
+ env->CheckGCAccess ();
96
97
97
98
auto isolate = env->isolate ;
98
99
auto str_maybe = string_maker (isolate);
@@ -1539,6 +1540,7 @@ napi_status NAPI_CDECL napi_get_prototype(napi_env env,
1539
1540
napi_status NAPI_CDECL napi_create_object (napi_env env, napi_value* result) {
1540
1541
CHECK_ENV (env);
1541
1542
CHECK_ARG (env, result);
1543
+ env->CheckGCAccess ();
1542
1544
1543
1545
*result = v8impl::JsValueFromV8LocalValue (v8::Object::New (env->isolate ));
1544
1546
@@ -1548,6 +1550,7 @@ napi_status NAPI_CDECL napi_create_object(napi_env env, napi_value* result) {
1548
1550
napi_status NAPI_CDECL napi_create_array (napi_env env, napi_value* result) {
1549
1551
CHECK_ENV (env);
1550
1552
CHECK_ARG (env, result);
1553
+ env->CheckGCAccess ();
1551
1554
1552
1555
*result = v8impl::JsValueFromV8LocalValue (v8::Array::New (env->isolate ));
1553
1556
@@ -1559,6 +1562,7 @@ napi_status NAPI_CDECL napi_create_array_with_length(napi_env env,
1559
1562
napi_value* result) {
1560
1563
CHECK_ENV (env);
1561
1564
CHECK_ARG (env, result);
1565
+ env->CheckGCAccess ();
1562
1566
1563
1567
*result =
1564
1568
v8impl::JsValueFromV8LocalValue (v8::Array::New (env->isolate , length));
@@ -1659,6 +1663,7 @@ napi_status NAPI_CDECL napi_create_double(napi_env env,
1659
1663
napi_value* result) {
1660
1664
CHECK_ENV (env);
1661
1665
CHECK_ARG (env, result);
1666
+ env->CheckGCAccess ();
1662
1667
1663
1668
*result =
1664
1669
v8impl::JsValueFromV8LocalValue (v8::Number::New (env->isolate , value));
@@ -1671,6 +1676,7 @@ napi_status NAPI_CDECL napi_create_int32(napi_env env,
1671
1676
napi_value* result) {
1672
1677
CHECK_ENV (env);
1673
1678
CHECK_ARG (env, result);
1679
+ env->CheckGCAccess ();
1674
1680
1675
1681
*result =
1676
1682
v8impl::JsValueFromV8LocalValue (v8::Integer::New (env->isolate , value));
@@ -1683,6 +1689,7 @@ napi_status NAPI_CDECL napi_create_uint32(napi_env env,
1683
1689
napi_value* result) {
1684
1690
CHECK_ENV (env);
1685
1691
CHECK_ARG (env, result);
1692
+ env->CheckGCAccess ();
1686
1693
1687
1694
*result = v8impl::JsValueFromV8LocalValue (
1688
1695
v8::Integer::NewFromUnsigned (env->isolate , value));
@@ -1695,6 +1702,7 @@ napi_status NAPI_CDECL napi_create_int64(napi_env env,
1695
1702
napi_value* result) {
1696
1703
CHECK_ENV (env);
1697
1704
CHECK_ARG (env, result);
1705
+ env->CheckGCAccess ();
1698
1706
1699
1707
*result = v8impl::JsValueFromV8LocalValue (
1700
1708
v8::Number::New (env->isolate , static_cast <double >(value)));
@@ -1707,6 +1715,7 @@ napi_status NAPI_CDECL napi_create_bigint_int64(napi_env env,
1707
1715
napi_value* result) {
1708
1716
CHECK_ENV (env);
1709
1717
CHECK_ARG (env, result);
1718
+ env->CheckGCAccess ();
1710
1719
1711
1720
*result =
1712
1721
v8impl::JsValueFromV8LocalValue (v8::BigInt::New (env->isolate , value));
@@ -1719,6 +1728,7 @@ napi_status NAPI_CDECL napi_create_bigint_uint64(napi_env env,
1719
1728
napi_value* result) {
1720
1729
CHECK_ENV (env);
1721
1730
CHECK_ARG (env, result);
1731
+ env->CheckGCAccess ();
1722
1732
1723
1733
*result = v8impl::JsValueFromV8LocalValue (
1724
1734
v8::BigInt::NewFromUnsigned (env->isolate , value));
@@ -1734,6 +1744,7 @@ napi_status NAPI_CDECL napi_create_bigint_words(napi_env env,
1734
1744
NAPI_PREAMBLE (env);
1735
1745
CHECK_ARG (env, words);
1736
1746
CHECK_ARG (env, result);
1747
+ env->CheckGCAccess ();
1737
1748
1738
1749
v8::Local<v8::Context> context = env->context ();
1739
1750
@@ -1753,6 +1764,7 @@ napi_status NAPI_CDECL napi_get_boolean(napi_env env,
1753
1764
napi_value* result) {
1754
1765
CHECK_ENV (env);
1755
1766
CHECK_ARG (env, result);
1767
+ env->CheckGCAccess ();
1756
1768
1757
1769
v8::Isolate* isolate = env->isolate ;
1758
1770
@@ -1770,6 +1782,7 @@ napi_status NAPI_CDECL napi_create_symbol(napi_env env,
1770
1782
napi_value* result) {
1771
1783
CHECK_ENV (env);
1772
1784
CHECK_ARG (env, result);
1785
+ env->CheckGCAccess ();
1773
1786
1774
1787
v8::Isolate* isolate = env->isolate ;
1775
1788
@@ -1792,6 +1805,7 @@ napi_status NAPI_CDECL node_api_symbol_for(napi_env env,
1792
1805
napi_value* result) {
1793
1806
CHECK_ENV (env);
1794
1807
CHECK_ARG (env, result);
1808
+ env->CheckGCAccess ();
1795
1809
1796
1810
napi_value js_description_string;
1797
1811
STATUS_CALL (napi_create_string_utf8 (
@@ -1838,6 +1852,7 @@ napi_status NAPI_CDECL napi_create_error(napi_env env,
1838
1852
CHECK_ENV (env);
1839
1853
CHECK_ARG (env, msg);
1840
1854
CHECK_ARG (env, result);
1855
+ env->CheckGCAccess ();
1841
1856
1842
1857
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1843
1858
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
@@ -1858,6 +1873,7 @@ napi_status NAPI_CDECL napi_create_type_error(napi_env env,
1858
1873
CHECK_ENV (env);
1859
1874
CHECK_ARG (env, msg);
1860
1875
CHECK_ARG (env, result);
1876
+ env->CheckGCAccess ();
1861
1877
1862
1878
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1863
1879
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
@@ -1878,6 +1894,7 @@ napi_status NAPI_CDECL napi_create_range_error(napi_env env,
1878
1894
CHECK_ENV (env);
1879
1895
CHECK_ARG (env, msg);
1880
1896
CHECK_ARG (env, result);
1897
+ env->CheckGCAccess ();
1881
1898
1882
1899
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1883
1900
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
@@ -1898,6 +1915,7 @@ napi_status NAPI_CDECL node_api_create_syntax_error(napi_env env,
1898
1915
CHECK_ENV (env);
1899
1916
CHECK_ARG (env, msg);
1900
1917
CHECK_ARG (env, result);
1918
+ env->CheckGCAccess ();
1901
1919
1902
1920
v8::Local<v8::Value> message_value = v8impl::V8LocalValueFromJsValue (msg);
1903
1921
RETURN_STATUS_IF_FALSE (env, message_value->IsString (), napi_string_expected);
0 commit comments