1 #include <stdlib.h>
2 #define NAPI_EXPERIMENTAL
3 #include <node_api.h>
4 
5 #define NAPI_CALL(env, call)                          \
6   do {                                                \
7     napi_status status = (call);                      \
8     if (status != napi_ok) {                          \
9       napi_throw_error((env), NULL, #call " failed"); \
10       return NULL;                                    \
11     }                                                 \
12   } while (0)
13 
14 static napi_value
GetCount(napi_env env, napi_callback_info info)15 GetCount(napi_env env, napi_callback_info info) {
16   napi_value result;
17   size_t* count;
18 
19   NAPI_CALL(env, napi_get_instance_data(env, (void**)&count));
20   NAPI_CALL(env, napi_create_uint32(env, *count, &result));
21 
22   return result;
23 }
24 
25 static napi_value
SetCount(napi_env env, napi_callback_info info)26 SetCount(napi_env env, napi_callback_info info) {
27   size_t* count;
28 
29   NAPI_CALL(env, napi_get_instance_data(env, (void**)&count));
30 
31   // Set the count to zero irrespective of what is passed into the setter.
32   *count = 0;
33 
34   return NULL;
35 }
36 
37 static void
IncrementCounter(napi_env env, void* data, void* hint)38 IncrementCounter(napi_env env, void* data, void* hint) {
39   size_t* count = data;
40   (*count) = (*count) + 1;
41 }
42 
43 static napi_value
NewWeak(napi_env env, napi_callback_info info)44 NewWeak(napi_env env, napi_callback_info info) {
45   napi_value result;
46   void* instance_data;
47 
48   NAPI_CALL(env, napi_create_object(env, &result));
49   NAPI_CALL(env, napi_get_instance_data(env, &instance_data));
50   NAPI_CALL(env, napi_add_finalizer(env,
51                                     result,
52                                     instance_data,
53                                     IncrementCounter,
54                                     NULL,
55                                     NULL));
56 
57   return result;
58 }
59 
60 static void
FreeCount(napi_env env, void* data, void* hint)61 FreeCount(napi_env env, void* data, void* hint) {
62   free(data);
63 }
64 
65 /* napi_value */
NAPI_MODULE_INITnull66 NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) {
67   napi_property_descriptor props[] = {
68     { "count", NULL, NULL, GetCount, SetCount, NULL, napi_enumerable, NULL },
69     { "newWeak", NULL, NewWeak, NULL, NULL, NULL, napi_enumerable, NULL }
70   };
71 
72   size_t* count = malloc(sizeof(*count));
73   *count = 0;
74 
75   NAPI_CALL(env, napi_define_properties(env,
76                                         exports,
77                                         sizeof(props) / sizeof(*props),
78                                         props));
79   NAPI_CALL(env, napi_set_instance_data(env, count, FreeCount, NULL));
80 
81   return exports;
82 }
83