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