• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <node_api.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 
5 #define NODE_API_CALL(call)                                                    \
6   do {                                                                         \
7     napi_status status = call;                                                 \
8     if (status != napi_ok) {                                                   \
9       fprintf(stderr, #call " failed: %d\n", status);                          \
10       abort();                                                                 \
11     }                                                                          \
12   } while (0)
13 
14 #define ABORT_IF_FALSE(condition)                                              \
15   if (!(condition)) {                                                          \
16     fprintf(stderr, #condition " failed\n");                                   \
17     abort();                                                                   \
18   }
19 
Runner(napi_env env,napi_callback_info info,napi_property_attributes attr)20 static napi_value Runner(napi_env env,
21                          napi_callback_info info,
22                          napi_property_attributes attr) {
23   napi_value argv[2], undefined, js_array_length, start, end;
24   size_t argc = 2;
25   napi_valuetype val_type = napi_undefined;
26   bool is_array = false;
27   uint32_t array_length = 0;
28   napi_value* native_array;
29 
30   // Validate params and retrieve start and end function.
31   NODE_API_CALL(napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
32   ABORT_IF_FALSE(argc == 2);
33   NODE_API_CALL(napi_typeof(env, argv[0], &val_type));
34   ABORT_IF_FALSE(val_type == napi_object);
35   NODE_API_CALL(napi_is_array(env, argv[1], &is_array));
36   ABORT_IF_FALSE(is_array);
37   NODE_API_CALL(napi_get_array_length(env, argv[1], &array_length));
38   NODE_API_CALL(napi_get_named_property(env, argv[0], "start", &start));
39   NODE_API_CALL(napi_typeof(env, start, &val_type));
40   ABORT_IF_FALSE(val_type == napi_function);
41   NODE_API_CALL(napi_get_named_property(env, argv[0], "end", &end));
42   NODE_API_CALL(napi_typeof(env, end, &val_type));
43   ABORT_IF_FALSE(val_type == napi_function);
44 
45   NODE_API_CALL(napi_get_undefined(env, &undefined));
46   NODE_API_CALL(napi_create_uint32(env, array_length, &js_array_length));
47 
48   // Copy objects into a native array.
49   native_array = malloc(array_length * sizeof(*native_array));
50   for (uint32_t idx = 0; idx < array_length; idx++) {
51     NODE_API_CALL(napi_get_element(env, argv[1], idx, &native_array[idx]));
52   }
53 
54   const napi_property_descriptor desc = {
55       "prop", NULL, NULL, NULL, NULL, js_array_length, attr, NULL};
56 
57   // Start the benchmark.
58   napi_call_function(env, argv[0], start, 0, NULL, NULL);
59 
60   for (uint32_t idx = 0; idx < array_length; idx++) {
61     NODE_API_CALL(napi_define_properties(env, native_array[idx], 1, &desc));
62   }
63 
64   // Conclude the benchmark.
65   NODE_API_CALL(
66       napi_call_function(env, argv[0], end, 1, &js_array_length, NULL));
67 
68   free(native_array);
69 
70   return undefined;
71 }
72 
RunFastPath(napi_env env,napi_callback_info info)73 static napi_value RunFastPath(napi_env env, napi_callback_info info) {
74   return Runner(env, info, napi_writable | napi_enumerable | napi_configurable);
75 }
76 
RunSlowPath(napi_env env,napi_callback_info info)77 static napi_value RunSlowPath(napi_env env, napi_callback_info info) {
78   return Runner(env, info, napi_writable | napi_enumerable);
79 }
80 
NAPI_MODULE_INIT()81 NAPI_MODULE_INIT() {
82   napi_property_descriptor props[] = {
83       {"runFastPath",
84        NULL,
85        RunFastPath,
86        NULL,
87        NULL,
88        NULL,
89        napi_writable | napi_configurable | napi_enumerable,
90        NULL},
91       {"runSlowPath",
92        NULL,
93        RunSlowPath,
94        NULL,
95        NULL,
96        NULL,
97        napi_writable | napi_configurable | napi_enumerable,
98        NULL},
99   };
100 
101   NODE_API_CALL(napi_define_properties(
102       env, exports, sizeof(props) / sizeof(*props), props));
103   return exports;
104 }
105