@@ -336,6 +336,7 @@ napi_status NAPICreateJSRuntime(napi_runtime *runtime) {
336
336
return napi_generic_failure;
337
337
}
338
338
339
+
339
340
return napi_ok;
340
341
}
341
342
@@ -354,10 +355,27 @@ napi_status NAPICreateEnv(napi_env *env, napi_runtime runtime) {
354
355
355
356
JS_SetRuntimeOpaque (runtime->runtime , *env);
356
357
358
+ JS_SetGCAfterCallback (runtime->runtime , [](JSRuntime* rt) {
359
+ auto env = (napi_env) JS_GetRuntimeOpaque (rt);
360
+ if (env->gcAfter != nullptr ) {
361
+ env->gcAfter ->finalizeCallback (env, env->gcAfter ->data , env->gcAfter ->finalizeHint );
362
+ }
363
+ });
364
+
365
+ JS_SetGCBeforeCallback (runtime->runtime , [](JSRuntime* rt) -> int {
366
+ auto env = (napi_env) JS_GetRuntimeOpaque (rt);
367
+ bool hint = true ;
368
+ if (env->gcAfter != nullptr ) {
369
+ env->gcAfter ->finalizeCallback (env, env->gcAfter ->data , &hint);
370
+ }
371
+ return hint;
372
+ });
373
+
357
374
// Resource - JSContext
358
375
JSContext *context = JS_NewContext (runtime->runtime );
359
376
// Create runtime atoms
360
377
378
+
361
379
(*env)->atoms .napi_external = JS_NewAtom (context, " napi_external" );
362
380
(*env)->atoms .registerFinalizer = JS_NewAtom (context, " register" );
363
381
(*env)->atoms .name = JS_NewAtom (context, " name" );
@@ -426,8 +444,6 @@ napi_status NAPICreateEnv(napi_env *env, napi_runtime runtime) {
426
444
JS_SetPropertyStr (context, globalValue, " gc" , gc);
427
445
428
446
JSValue jsNativeEngine = (JSValue) JS_MKPTR (JS_TAG_INT, (*env));
429
-
430
-
431
447
JSValue FinalizationRegistry = JS_GetPropertyStr (context, globalValue, " FinalizationRegistry" );
432
448
JSValue FinalizeCallback = JS_NewCFunction (context,
433
449
[](JSContext *ctx, JSValueConst this_val, int argc,
@@ -497,6 +513,7 @@ napi_status NAPICreateEnv(napi_env *env, napi_runtime runtime) {
497
513
JS_EVAL_TYPE_GLOBAL);
498
514
JS_FreeValue ((*env)->context , func);
499
515
516
+
500
517
return napi_clear_last_error ((*env));
501
518
}
502
519
@@ -1102,7 +1119,7 @@ napi_status napi_get_reference_value(napi_env env, napi_ref ref, napi_value *res
1102
1119
return napi_set_last_error (env, status);
1103
1120
}
1104
1121
1105
- *result = (napi_value) &handle ->value ;
1122
+ *result = (napi_value) &ref ->value ;
1106
1123
}
1107
1124
1108
1125
return napi_clear_last_error (env);
@@ -3449,13 +3466,17 @@ napi_status napi_call_function(napi_env env, napi_value thisValue, napi_value fu
3449
3466
JSValue returnValue = JS_Call (env->context , jsFunction, *((JSValue *) thisValue), (int ) argc,
3450
3467
args);
3451
3468
3469
+
3452
3470
if (args) {
3453
3471
free (args);
3454
3472
}
3455
3473
3474
+ napi_run_microtasks (env);
3475
+
3456
3476
if (JS_IsException (returnValue)) {
3457
- napi_close_handle_scope (env, handleScope);
3458
3477
print_exception (env, returnValue);
3478
+ napi_close_handle_scope (env, handleScope);
3479
+ *result = nullptr ;
3459
3480
return napi_set_last_error (env, napi_pending_exception);
3460
3481
}
3461
3482
@@ -4215,23 +4236,18 @@ napi_check_object_type_tag(napi_env env, napi_value object, napi_type_tag tag, b
4215
4236
}
4216
4237
4217
4238
napi_status napi_run_microtasks (napi_env env) {
4218
- if (TRUTHY (!env))
4219
- return napi_invalid_arg;
4220
-
4221
- int error = 1 ;
4239
+ CHECK_ARG (env)
4240
+ int error;
4222
4241
do {
4223
4242
JSContext *context;
4224
4243
error = JS_ExecutePendingJob (JS_GetRuntime (env->context ), &context);
4225
4244
if (error == -1 ) {
4226
- // Under normal circumstances, JS_ExecutePendingJob returns -1
4227
- // Represents engine internal exceptions, such as memory allocation failure, etc.
4228
- // TODO(ChasonTang): Test when Promise throws an exception
4229
4245
JSValue inlineExceptionValue = JS_GetException (context);
4230
-
4231
4246
JS_FreeValue (context, inlineExceptionValue);
4247
+ return napi_ok;
4232
4248
}
4233
4249
} while (error != 0 );
4234
-
4250
+
4235
4251
return napi_ok;
4236
4252
}
4237
4253
@@ -4254,12 +4270,9 @@ napi_status napi_run_script(napi_env env,
4254
4270
JSValue eval_result;
4255
4271
const char *cScript = JS_ToCString (env->context , *((JSValue *) script));
4256
4272
eval_result = JS_Eval (env->context , cScript, strlen (cScript), file, JS_EVAL_TYPE_GLOBAL);
4257
-
4258
- napi_run_microtasks (env);
4259
-
4260
4273
// 3. Free the script char *
4261
4274
JS_FreeCString (env->context , cScript);
4262
-
4275
+ napi_run_microtasks (env);
4263
4276
if (JS_IsException (eval_result)) {
4264
4277
JSValue exception = JS_GetException (env->context );
4265
4278
const char *exceptionMessage = JS_ToCString (env->context , exception );
@@ -4279,6 +4292,7 @@ napi_status napi_run_script(napi_env env,
4279
4292
JS_FreeValue (env->context , eval_result);
4280
4293
}
4281
4294
4295
+
4282
4296
return napi_clear_last_error (env);
4283
4297
}
4284
4298
@@ -4375,6 +4389,14 @@ napi_status NAPIFreeEnv(napi_env env) {
4375
4389
free (env->instanceData );
4376
4390
};
4377
4391
4392
+ if (env->gcAfter != nullptr ) {
4393
+ free (env->gcAfter );
4394
+ }
4395
+
4396
+ if (env->gcBefore != nullptr ) {
4397
+ free (env->gcBefore );
4398
+ }
4399
+
4378
4400
// Free Atoms
4379
4401
JS_FreeAtom (env->context , env->atoms .napi_external );
4380
4402
JS_FreeAtom (env->context , env->atoms .registerFinalizer );
@@ -4401,16 +4423,29 @@ napi_status NAPIFreeEnv(napi_env env) {
4401
4423
}
4402
4424
4403
4425
4404
- napi_status napi_set_gc_being_callback (napi_env env, napi_callback cb, void * data) {
4426
+ napi_status napi_set_gc_begin_callback (napi_env env, napi_finalize cb, void * data) {
4405
4427
CHECK_ARG (env)
4406
4428
CHECK_ARG (cb)
4407
4429
4430
+ auto info = (ExternalInfo *) malloc (sizeof (ExternalInfo));
4431
+ info->data = data;
4432
+ info->finalizeCallback = cb;
4433
+ info->finalizeHint = nullptr ;
4434
+ env->gcBefore = info;
4435
+
4408
4436
return napi_clear_last_error (env);
4409
4437
}
4410
4438
4411
- napi_status napi_set_gc_end_callback (napi_env env, napi_callback cb, void * data) {
4439
+ napi_status napi_set_gc_finish_callback (napi_env env, napi_finalize cb, void * data ) {
4412
4440
CHECK_ARG (env)
4413
4441
CHECK_ARG (cb)
4414
4442
4443
+ auto info = (ExternalInfo *) malloc (sizeof (ExternalInfo));
4444
+ info->data = data;
4445
+ info->finalizeCallback = cb;
4446
+ info->finalizeHint = nullptr ;
4447
+
4448
+ env->gcAfter = info;
4449
+
4415
4450
return napi_clear_last_error (env);
4416
- }
4451
+ }
0 commit comments