Skip to content

Commit 694562c

Browse files
authored
run finalizers directly from GC (#72)
1 parent 8b4551b commit 694562c

32 files changed

Lines changed: 475 additions & 57 deletions

.vscode/c_cpp_properties.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"includePath": [
44
"${default}",
55
// "${env:USERPROFILE}/AppData/Local/node-gyp/Cache/16.15.0/include/node"
6-
"${workspaceFolder}/packages/emnapi/include"
6+
"${workspaceFolder}/packages/emnapi/include",
7+
"${workspaceFolder}/node_modules/node-addon-api"
78
],
89
"defines": ["NAPI_DISABLE_CPP_EXCEPTIONS", "NODE_ADDON_API_ENABLE_MAYBE"],
910
"clPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.28.29910\\bin\\Hostx64\\x64\\cl.exe",

packages/emnapi/include/js_native_api.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,16 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_add_finalizer(napi_env env,
523523

524524
#endif // NAPI_VERSION >= 5
525525

526+
#ifdef NAPI_EXPERIMENTAL
527+
528+
NAPI_EXTERN napi_status NAPI_CDECL
529+
node_api_post_finalizer(napi_env env,
530+
napi_finalize finalize_cb,
531+
void* finalize_data,
532+
void* finalize_hint);
533+
534+
#endif // NAPI_EXPERIMENTAL
535+
526536
#if NAPI_VERSION >= 6
527537

528538
// BigInt

packages/emnapi/src/async_context.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ napi_async_init(napi_env env,
2121
napi_value async_resource_name,
2222
napi_async_context* result) {
2323
CHECK_ENV(env);
24+
_emnapi_env_check_gc_access(env);
2425
CHECK_ARG(env, async_resource_name);
2526
CHECK_ARG(env, result);
2627

@@ -39,6 +40,7 @@ napi_async_init(napi_env env,
3940
napi_status napi_async_destroy(napi_env env,
4041
napi_async_context async_context) {
4142
CHECK_ENV(env);
43+
_emnapi_env_check_gc_access(env);
4244
CHECK_ARG(env, async_context);
4345

4446
napi_status status = _emnapi_async_destroy_js(async_context);

packages/emnapi/src/async_work.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ napi_status napi_create_async_work(napi_env env,
149149
napi_async_work* result) {
150150
#if EMNAPI_HAVE_THREADS
151151
CHECK_ENV(env);
152+
_emnapi_env_check_gc_access(env);
152153
CHECK_ARG(env, execute);
153154
CHECK_ARG(env, result);
154155

@@ -188,6 +189,7 @@ napi_status napi_create_async_work(napi_env env,
188189
napi_status napi_delete_async_work(napi_env env, napi_async_work work) {
189190
#if EMNAPI_HAVE_THREADS
190191
CHECK_ENV(env);
192+
_emnapi_env_check_gc_access(env);
191193
CHECK_ARG(env, work);
192194

193195
async_work_delete(work);

packages/emnapi/src/core/async-work.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ var _napi_create_async_work = singleThreadAsyncWork
227227
? function (env: napi_env, resource: napi_value, resource_name: napi_value, execute: number, complete: number, data: number, result: number): napi_status {
228228
$CHECK_ENV!(env)
229229
const envObject = emnapiCtx.envStore.get(env)!
230+
envObject.checkGCAccess()
230231
$CHECK_ARG!(envObject, execute)
231232
$CHECK_ARG!(envObject, result)
232233

@@ -249,6 +250,7 @@ var _napi_create_async_work = singleThreadAsyncWork
249250
: function (env: napi_env, resource: napi_value, resource_name: napi_value, execute: number, complete: number, data: number, result: number): napi_status {
250251
$CHECK_ENV!(env)
251252
const envObject = emnapiCtx.envStore.get(env)!
253+
envObject.checkGCAccess()
252254
$CHECK_ARG!(envObject, execute)
253255
$CHECK_ARG!(envObject, result)
254256

@@ -284,6 +286,7 @@ var _napi_delete_async_work = singleThreadAsyncWork
284286
? function (env: napi_env, work: number): napi_status {
285287
$CHECK_ENV!(env)
286288
const envObject = emnapiCtx.envStore.get(env)!
289+
envObject.checkGCAccess()
287290
$CHECK_ARG!(envObject, work)
288291

289292
emnapiAWST.remove(work)
@@ -292,6 +295,7 @@ var _napi_delete_async_work = singleThreadAsyncWork
292295
: function (env: napi_env, work: number): napi_status {
293296
$CHECK_ENV!(env)
294297
const envObject = emnapiCtx.envStore.get(env)!
298+
envObject.checkGCAccess()
295299
$CHECK_ARG!(envObject, work)
296300

297301
const resource = emnapiAWMT.getResource(work)

packages/emnapi/src/emnapi_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ napi_status _emnapi_node_make_callback(napi_env env,
156156
double trigger_async_id,
157157
napi_value* result);
158158

159+
EMNAPI_INTERNAL_EXTERN
160+
void _emnapi_env_check_gc_access(napi_env env);
161+
159162
#define EMNAPI_ASYNC_RESOURCE_CTOR(env, res, name, ar) \
160163
do { \
161164
EMNAPI_ASSERT_CALL(napi_create_reference((env), (res), 1, &(ar)->resource_)); \

packages/emnapi/src/emscripten/async-work.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
function _napi_create_async_work (env: napi_env, resource: napi_value, resource_name: napi_value, execute: number, complete: number, data: number, result: number): napi_status {
22
$CHECK_ENV!(env)
33
const envObject = emnapiCtx.envStore.get(env)!
4+
envObject.checkGCAccess()
45
$CHECK_ARG!(envObject, execute)
56
$CHECK_ARG!(envObject, result)
67

@@ -24,6 +25,7 @@ function _napi_create_async_work (env: napi_env, resource: napi_value, resource_
2425
function _napi_delete_async_work (env: napi_env, work: number): napi_status {
2526
$CHECK_ENV!(env)
2627
const envObject = emnapiCtx.envStore.get(env)!
28+
envObject.checkGCAccess()
2729
$CHECK_ARG!(envObject, work)
2830

2931
emnapiAWST.remove(work)

packages/emnapi/src/error.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ function node_api_throw_syntax_error (env: napi_env, code: const_char_p, msg: co
8585
function napi_is_exception_pending (env: napi_env, result: Pointer<bool>): napi_status {
8686
$CHECK_ENV!(env)
8787
const envObject = emnapiCtx.envStore.get(env)!
88+
envObject.checkGCAccess()
8889
$CHECK_ARG!(envObject, result)
8990
// eslint-disable-next-line @typescript-eslint/no-unused-vars
9091
const r = envObject.tryCatch.hasCaught()
@@ -96,6 +97,7 @@ function napi_is_exception_pending (env: napi_env, result: Pointer<bool>): napi_
9697
function napi_create_error (env: napi_env, code: napi_value, msg: napi_value, result: Pointer<napi_value>): napi_status {
9798
$CHECK_ENV!(env)
9899
const envObject = emnapiCtx.envStore.get(env)!
100+
envObject.checkGCAccess()
99101
$CHECK_ARG!(envObject, msg)
100102
$CHECK_ARG!(envObject, result)
101103
const msgValue = emnapiCtx.handleStore.get(msg)!.value
@@ -123,6 +125,7 @@ function napi_create_error (env: napi_env, code: napi_value, msg: napi_value, re
123125
function napi_create_type_error (env: napi_env, code: napi_value, msg: napi_value, result: Pointer<napi_value>): napi_status {
124126
$CHECK_ENV!(env)
125127
const envObject = emnapiCtx.envStore.get(env)!
128+
envObject.checkGCAccess()
126129
$CHECK_ARG!(envObject, msg)
127130
$CHECK_ARG!(envObject, result)
128131
const msgValue = emnapiCtx.handleStore.get(msg)!.value
@@ -149,6 +152,7 @@ function napi_create_type_error (env: napi_env, code: napi_value, msg: napi_valu
149152
function napi_create_range_error (env: napi_env, code: napi_value, msg: napi_value, result: Pointer<napi_value>): napi_status {
150153
$CHECK_ENV!(env)
151154
const envObject = emnapiCtx.envStore.get(env)!
155+
envObject.checkGCAccess()
152156
$CHECK_ARG!(envObject, msg)
153157
$CHECK_ARG!(envObject, result)
154158
const msgValue = emnapiCtx.handleStore.get(msg)!.value
@@ -174,6 +178,7 @@ function napi_create_range_error (env: napi_env, code: napi_value, msg: napi_val
174178
function node_api_create_syntax_error (env: napi_env, code: napi_value, msg: napi_value, result: Pointer<napi_value>): napi_status {
175179
$CHECK_ENV!(env)
176180
const envObject = emnapiCtx.envStore.get(env)!
181+
envObject.checkGCAccess()
177182
$CHECK_ARG!(envObject, msg)
178183
$CHECK_ARG!(envObject, result)
179184
const msgValue = emnapiCtx.handleStore.get(msg)!.value
@@ -199,6 +204,7 @@ function node_api_create_syntax_error (env: napi_env, code: napi_value, msg: nap
199204
function napi_get_and_clear_last_exception (env: napi_env, result: Pointer<napi_value>): napi_status {
200205
$CHECK_ENV!(env)
201206
const envObject = emnapiCtx.envStore.get(env)!
207+
envObject.checkGCAccess()
202208
$CHECK_ARG!(envObject, result)
203209
$from64('result')
204210

packages/emnapi/src/function.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ function napi_get_new_target (
167167
const envObject = emnapiCtx.envStore.get(env)!
168168
// if (!cbinfo) return envObject.setLastError(napi_status.napi_invalid_arg)
169169
$CHECK_ARG!(envObject, result)
170+
envObject.checkGCAccess()
170171

171172
$from64('result')
172173

packages/emnapi/src/life.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
function napi_open_handle_scope (env: napi_env, result: Pointer<napi_handle_scope>): napi_status {
22
$CHECK_ENV!(env)
33
const envObject = emnapiCtx.envStore.get(env)!
4+
envObject.checkGCAccess()
45
$CHECK_ARG!(envObject, result)
56
// eslint-disable-next-line @typescript-eslint/no-unused-vars
67
const scope = emnapiCtx.openScope(envObject)
@@ -12,6 +13,7 @@ function napi_open_handle_scope (env: napi_env, result: Pointer<napi_handle_scop
1213
function napi_close_handle_scope (env: napi_env, scope: napi_handle_scope): napi_status {
1314
$CHECK_ENV!(env)
1415
const envObject = emnapiCtx.envStore.get(env)!
16+
envObject.checkGCAccess()
1517
$CHECK_ARG!(envObject, scope)
1618
if ((envObject.openHandleScopes === 0)) {
1719
return napi_status.napi_handle_scope_mismatch
@@ -24,6 +26,7 @@ function napi_close_handle_scope (env: napi_env, scope: napi_handle_scope): napi
2426
function napi_open_escapable_handle_scope (env: napi_env, result: Pointer<napi_escapable_handle_scope>): napi_status {
2527
$CHECK_ENV!(env)
2628
const envObject = emnapiCtx.envStore.get(env)!
29+
envObject.checkGCAccess()
2730
$CHECK_ARG!(envObject, result)
2831
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2932
const scope = emnapiCtx.openScope(envObject)
@@ -35,6 +38,7 @@ function napi_open_escapable_handle_scope (env: napi_env, result: Pointer<napi_e
3538
function napi_close_escapable_handle_scope (env: napi_env, scope: napi_escapable_handle_scope): napi_status {
3639
$CHECK_ENV!(env)
3740
const envObject = emnapiCtx.envStore.get(env)!
41+
envObject.checkGCAccess()
3842
$CHECK_ARG!(envObject, scope)
3943
if ((envObject.openHandleScopes === 0)) {
4044
return napi_status.napi_handle_scope_mismatch
@@ -47,6 +51,7 @@ function napi_close_escapable_handle_scope (env: napi_env, scope: napi_escapable
4751
function napi_escape_handle (env: napi_env, scope: napi_escapable_handle_scope, escapee: napi_value, result: Pointer<napi_value>): napi_status {
4852
$CHECK_ENV!(env)
4953
const envObject = emnapiCtx.envStore.get(env)!
54+
envObject.checkGCAccess()
5055
$CHECK_ARG!(envObject, scope)
5156
$CHECK_ARG!(envObject, escapee)
5257
$CHECK_ARG!(envObject, result)
@@ -72,6 +77,7 @@ function napi_create_reference (
7277
): napi_status {
7378
$CHECK_ENV!(env)
7479
const envObject = emnapiCtx.envStore.get(env)!
80+
envObject.checkGCAccess()
7581
$CHECK_ARG!(envObject, value)
7682
$CHECK_ARG!(envObject, result)
7783

@@ -94,6 +100,7 @@ function napi_delete_reference (
94100
): napi_status {
95101
$CHECK_ENV!(env)
96102
const envObject = emnapiCtx.envStore.get(env)!
103+
envObject.checkGCAccess()
97104
$CHECK_ARG!(envObject, ref)
98105
emnapiCtx.refStore.get(ref)!.dispose()
99106
return envObject.clearLastError()
@@ -106,6 +113,7 @@ function napi_reference_ref (
106113
): napi_status {
107114
$CHECK_ENV!(env)
108115
const envObject = emnapiCtx.envStore.get(env)!
116+
envObject.checkGCAccess()
109117
$CHECK_ARG!(envObject, ref)
110118
// eslint-disable-next-line @typescript-eslint/no-unused-vars
111119
const count = emnapiCtx.refStore.get(ref)!.ref()
@@ -123,6 +131,7 @@ function napi_reference_unref (
123131
): napi_status {
124132
$CHECK_ENV!(env)
125133
const envObject = emnapiCtx.envStore.get(env)!
134+
envObject.checkGCAccess()
126135
$CHECK_ARG!(envObject, ref)
127136
const reference = emnapiCtx.refStore.get(ref)!
128137
const refcount = reference.refCount()
@@ -146,6 +155,7 @@ function napi_get_reference_value (
146155
): napi_status {
147156
$CHECK_ENV!(env)
148157
const envObject = emnapiCtx.envStore.get(env)!
158+
envObject.checkGCAccess()
149159
$CHECK_ARG!(envObject, ref)
150160
$CHECK_ARG!(envObject, result)
151161
const reference = emnapiCtx.refStore.get(ref)!

0 commit comments

Comments
 (0)