@@ -30,6 +30,78 @@ static napi_value TestFunctionName(napi_env env, napi_callback_info info) {
3030 return NULL ;
3131}
3232
33+ static void finalize_function (napi_env env , void * data , void * hint ) {
34+ napi_ref ref = data ;
35+
36+ // Retrieve the JavaScript undefined value.
37+ napi_value undefined ;
38+ NAPI_CALL_RETURN_VOID (env , napi_get_undefined (env , & undefined ));
39+
40+ // Retrieve the JavaScript function we must call.
41+ napi_value js_function ;
42+ NAPI_CALL_RETURN_VOID (env , napi_get_reference_value (env , ref , & js_function ));
43+
44+ // Call the JavaScript function to indicate that the generated JavaScript
45+ // function is about to be gc-ed.
46+ NAPI_CALL_RETURN_VOID (env , napi_call_function (env ,
47+ undefined ,
48+ js_function ,
49+ 0 ,
50+ NULL ,
51+ NULL ));
52+
53+ // Destroy the persistent reference to the function we just called so as to
54+ // properly clean up.
55+ NAPI_CALL_RETURN_VOID (env , napi_delete_reference (env , ref ));
56+ }
57+
58+ static napi_value MakeTrackedFunction (napi_env env , napi_callback_info info ) {
59+ size_t argc = 1 ;
60+ napi_value js_finalize_cb ;
61+ napi_valuetype arg_type ;
62+
63+ // Retrieve and validate from the arguments the function we will use to
64+ // indicate to JavaScript that the function we are about to create is about to
65+ // be gc-ed.
66+ NAPI_CALL (env , napi_get_cb_info (env ,
67+ info ,
68+ & argc ,
69+ & js_finalize_cb ,
70+ NULL ,
71+ NULL ));
72+ NAPI_ASSERT (env , argc == 1 , "Wrong number of arguments" );
73+ NAPI_CALL (env , napi_typeof (env , js_finalize_cb , & arg_type ));
74+ NAPI_ASSERT (env , arg_type == napi_function , "Argument must be a function" );
75+
76+ // Dynamically create a function.
77+ napi_value result ;
78+ NAPI_CALL (env , napi_create_function (env ,
79+ "TrackedFunction" ,
80+ NAPI_AUTO_LENGTH ,
81+ TestFunctionName ,
82+ NULL ,
83+ & result ));
84+
85+ // Create a strong reference to the function we will call when the tracked
86+ // function is about to be gc-ed.
87+ napi_ref js_finalize_cb_ref ;
88+ NAPI_CALL (env , napi_create_reference (env ,
89+ js_finalize_cb ,
90+ 1 ,
91+ & js_finalize_cb_ref ));
92+
93+ // Attach a finalizer to the dynamically created function and pass it the
94+ // strong reference we created in the previous step.
95+ NAPI_CALL (env , napi_wrap (env ,
96+ result ,
97+ js_finalize_cb_ref ,
98+ finalize_function ,
99+ NULL ,
100+ NULL ));
101+
102+ return result ;
103+ }
104+
33105static napi_value Init (napi_env env , napi_value exports ) {
34106 napi_value fn1 ;
35107 NAPI_CALL (env , napi_create_function (
@@ -43,9 +115,21 @@ static napi_value Init(napi_env env, napi_value exports) {
43115 NAPI_CALL (env , napi_create_function (
44116 env , "Name_extra" , 5 , TestFunctionName , NULL , & fn3 ));
45117
118+ napi_value fn4 ;
119+ NAPI_CALL (env , napi_create_function (env ,
120+ "MakeTrackedFunction" ,
121+ NAPI_AUTO_LENGTH ,
122+ MakeTrackedFunction ,
123+ NULL ,
124+ & fn4 ));
125+
46126 NAPI_CALL (env , napi_set_named_property (env , exports , "TestCall" , fn1 ));
47127 NAPI_CALL (env , napi_set_named_property (env , exports , "TestName" , fn2 ));
48128 NAPI_CALL (env , napi_set_named_property (env , exports , "TestNameShort" , fn3 ));
129+ NAPI_CALL (env , napi_set_named_property (env ,
130+ exports ,
131+ "MakeTrackedFunction" ,
132+ fn4 ));
49133
50134 return exports ;
51135}
0 commit comments