• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <js_native_api.h>
4 #include "../common.h"
5 
6 typedef struct {
7   size_t value;
8   bool print;
9   napi_ref js_cb_ref;
10 } AddonData;
11 
Increment(napi_env env,napi_callback_info info)12 static napi_value Increment(napi_env env, napi_callback_info info) {
13   AddonData* data;
14   napi_value result;
15 
16   NAPI_CALL(env, napi_get_instance_data(env, (void**)&data));
17   NAPI_CALL(env, napi_create_uint32(env, ++data->value, &result));
18 
19   return result;
20 }
21 
DeleteAddonData(napi_env env,void * raw_data,void * hint)22 static void DeleteAddonData(napi_env env, void* raw_data, void* hint) {
23   AddonData* data = raw_data;
24   if (data->print) {
25     printf("deleting addon data\n");
26   }
27   if (data->js_cb_ref != NULL) {
28     NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, data->js_cb_ref));
29   }
30   free(data);
31 }
32 
SetPrintOnDelete(napi_env env,napi_callback_info info)33 static napi_value SetPrintOnDelete(napi_env env, napi_callback_info info) {
34   AddonData* data;
35 
36   NAPI_CALL(env, napi_get_instance_data(env, (void**)&data));
37   data->print = true;
38 
39   return NULL;
40 }
41 
TestFinalizer(napi_env env,void * raw_data,void * hint)42 static void TestFinalizer(napi_env env, void* raw_data, void* hint) {
43   (void) raw_data;
44   (void) hint;
45 
46   AddonData* data;
47   NAPI_CALL_RETURN_VOID(env, napi_get_instance_data(env, (void**)&data));
48   napi_value js_cb, undefined;
49   NAPI_CALL_RETURN_VOID(env,
50       napi_get_reference_value(env, data->js_cb_ref, &js_cb));
51   NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
52   NAPI_CALL_RETURN_VOID(env,
53       napi_call_function(env, undefined, js_cb, 0, NULL, NULL));
54   NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, data->js_cb_ref));
55   data->js_cb_ref = NULL;
56 }
57 
ObjectWithFinalizer(napi_env env,napi_callback_info info)58 static napi_value ObjectWithFinalizer(napi_env env, napi_callback_info info) {
59   AddonData* data;
60   napi_value result, js_cb;
61   size_t argc = 1;
62 
63   NAPI_CALL(env, napi_get_instance_data(env, (void**)&data));
64   NAPI_ASSERT(env, data->js_cb_ref == NULL, "reference must be NULL");
65   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &js_cb, NULL, NULL));
66   NAPI_CALL(env, napi_create_object(env, &result));
67   NAPI_CALL(env,
68       napi_add_finalizer(env, result, NULL, TestFinalizer, NULL, NULL));
69   NAPI_CALL(env, napi_create_reference(env, js_cb, 1, &data->js_cb_ref));
70 
71   return result;
72 }
73 
74 EXTERN_C_START
Init(napi_env env,napi_value exports)75 napi_value Init(napi_env env, napi_value exports) {
76   AddonData* data = malloc(sizeof(*data));
77   data->value = 41;
78   data->print = false;
79   data->js_cb_ref = NULL;
80 
81   NAPI_CALL(env, napi_set_instance_data(env, data, DeleteAddonData, NULL));
82 
83   napi_property_descriptor props[] = {
84     DECLARE_NAPI_PROPERTY("increment", Increment),
85     DECLARE_NAPI_PROPERTY("setPrintOnDelete", SetPrintOnDelete),
86     DECLARE_NAPI_PROPERTY("objectWithFinalizer", ObjectWithFinalizer),
87   };
88 
89   NAPI_CALL(env, napi_define_properties(env,
90                                         exports,
91                                         sizeof(props) / sizeof(*props),
92                                         props));
93 
94   return exports;
95 }
96 EXTERN_C_END
97