1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include "hiperf_client_napi.h"
16#include <cstdio>
17#include <string>
18#include "hiperf_hilog.h"
19#include "hiperf_client.h"
20#include "napi/native_api.h"
21#include "napi/native_node_api.h"
22
23namespace OHOS {
24namespace Developtools {
25namespace HiPerf {
26namespace HiperfClient {
27static std::unique_ptr<HiperfClient::Client> g_hiperfClient =
28    std::make_unique<HiperfClient::Client>();
29
30static std::unique_ptr<HiperfClient::RecordOption> g_hiperfRecordOption =
31    std::make_unique<HiperfClient::RecordOption>();
32
33static std::vector<std::string> StringSplit(std::string source, const std::string &split = ",")
34{
35    size_t pos = 0;
36    std::vector<std::string> result;
37
38    // find
39    while ((pos = source.find(split)) != std::string::npos) {
40        // split
41        std::string token = source.substr(0, pos);
42        if (!token.empty()) {
43            result.push_back(token);
44        }
45        source.erase(0, pos + split.length());
46    }
47    // add last token
48    if (!source.empty()) {
49        result.push_back(source);
50    }
51    return result;
52}
53
54static std::vector<int> StringSplitToInt(std::string source, const std::string &split = ",")
55{
56    size_t pos = 0;
57    std::vector<int> result;
58
59    // find
60    while ((pos = source.find(split)) != std::string::npos) {
61        // split
62        std::string token = source.substr(0, pos);
63        if (!token.empty()) {
64            result.push_back(std::stoi(token));
65        }
66        source.erase(0, pos + split.length());
67    }
68    // add last token
69    if (!source.empty()) {
70        result.push_back(std::stoi(source));
71    }
72    return result;
73}
74
75static std::string GetJsStringFromOption(const napi_env &env, const napi_callback_info &info)
76{
77    size_t argc = 1;
78    napi_value args[1] = {0};
79    NAPI_CALL_BASE(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), "");
80    NAPI_ASSERT_BASE(env, argc == 1, "requires 1 parameter", "");
81
82    napi_valuetype inputType = napi_undefined;
83    napi_typeof(env, args[0], &inputType);
84    NAPI_ASSERT_BASE(env, inputType == napi_string, "type mismatch for parameter path", "");
85
86    char value[PATH_MAX] = {0};
87    size_t valueLen = 0;
88    napi_get_value_string_utf8(env, args[0], value, sizeof(value), &valueLen);
89    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}s", value);
90    return std::string(value);
91}
92
93static bool GetBoolFromOption(const napi_env &env, const napi_callback_info &info)
94{
95    size_t argc = 1;
96    napi_value args[1] = {0};
97    NAPI_CALL_BASE(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), false);
98    NAPI_ASSERT_BASE(env, argc == 1, "requires 1 parameter", false);
99
100    napi_valuetype inputType = napi_undefined;
101    napi_typeof(env, args[0], &inputType);
102    NAPI_ASSERT_BASE(env, (inputType == napi_boolean), "type mismatch for parameter path", false);
103
104    bool result = false;
105    napi_get_value_bool(env, args[0], &result);
106    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
107    return result;
108}
109
110static uint32_t GetUintFromOption(const napi_env &env, const napi_callback_info &info)
111{
112    size_t argc = 1;
113    napi_value args[1] = {0};
114    NAPI_CALL_BASE(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), 0);
115    NAPI_ASSERT_BASE(env, argc == 1, "requires 1 parameter", 0);
116
117    napi_valuetype inputType = napi_undefined;
118    napi_typeof(env, args[0], &inputType);
119    NAPI_ASSERT_BASE(env, (inputType == napi_number), "type mismatch for parameter path", false);
120
121    uint32_t result = 0;
122    napi_get_value_uint32(env, args[0], &result);
123    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
124    return result;
125}
126
127static napi_value ResetOption(napi_env env, napi_callback_info info)
128{
129    napi_value napiValue = nullptr;
130    bool result = true;
131    g_hiperfRecordOption = std::make_unique<HiperfClient::RecordOption>();
132
133    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
134    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
135    return napiValue;
136}
137
138static napi_value SetOutputFilename(napi_env env, napi_callback_info info)
139{
140    napi_value napiValue = nullptr;
141    bool result = true;
142    const std::string option = GetJsStringFromOption(env, info);
143    g_hiperfRecordOption->SetOutputFilename(option);
144
145    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
146    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
147    return napiValue;
148}
149
150static napi_value GetOutputFileName(napi_env env, napi_callback_info info)
151{
152    napi_value napiValue = nullptr;
153    std::string result = g_hiperfRecordOption->GetOutputFileName();
154    NAPI_CALL(env, napi_create_string_utf8(env, result.c_str(), result.size(), &napiValue));
155
156    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}s", result.c_str());
157    return napiValue;
158}
159
160static napi_value SetTargetSystemWide(napi_env env, napi_callback_info info)
161{
162    napi_value napiValue = nullptr;
163    bool result = true;
164    bool enable = GetBoolFromOption(env, info);
165    g_hiperfRecordOption->SetTargetSystemWide(enable);
166
167    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
168    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
169    return napiValue;
170}
171
172static napi_value SetCompressData(napi_env env, napi_callback_info info)
173{
174    napi_value napiValue = nullptr;
175    bool result = true;
176    bool enable = GetBoolFromOption(env, info);
177    g_hiperfRecordOption->SetCompressData(enable);
178
179    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
180    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
181    return napiValue;
182}
183
184static napi_value SetSelectCpus(napi_env env, napi_callback_info info)
185{
186    napi_value napiValue = nullptr;
187    bool result = true;
188    std::string option = GetJsStringFromOption(env, info);
189    g_hiperfRecordOption->SetSelectCpus(StringSplitToInt(option));
190
191    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
192    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
193    return napiValue;
194}
195
196static napi_value SetTimeStopSec(napi_env env, napi_callback_info info)
197{
198    napi_value napiValue = nullptr;
199    bool result = true;
200    uint32_t option = GetUintFromOption(env, info);
201    g_hiperfRecordOption->SetTimeStopSec(option);
202
203    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
204    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
205    return napiValue;
206}
207
208static napi_value SetFrequency(napi_env env, napi_callback_info info)
209{
210    napi_value napiValue = nullptr;
211    bool result = true;
212    uint32_t option = GetUintFromOption(env, info);
213    g_hiperfRecordOption->SetFrequency(option);
214
215    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
216    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
217    return napiValue;
218}
219
220static napi_value SetPeriod(napi_env env, napi_callback_info info)
221{
222    napi_value napiValue = nullptr;
223    bool result = true;
224    uint32_t option = GetUintFromOption(env, info);
225    g_hiperfRecordOption->SetPeriod(option);
226
227    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
228    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
229    return napiValue;
230}
231
232static napi_value SetSelectEvents(napi_env env, napi_callback_info info)
233{
234    napi_value napiValue = nullptr;
235    bool result = true;
236    std::string option = GetJsStringFromOption(env, info);
237    g_hiperfRecordOption->SetSelectEvents(StringSplit(option));
238
239    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
240    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
241    return napiValue;
242}
243static napi_value SetSelectGroups(napi_env env, napi_callback_info info)
244{
245    napi_value napiValue = nullptr;
246    bool result = true;
247    std::string option = GetJsStringFromOption(env, info);
248    g_hiperfRecordOption->SetSelectGroups(StringSplit(option));
249
250    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
251    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
252    return napiValue;
253}
254static napi_value SetNoInherit(napi_env env, napi_callback_info info)
255{
256    napi_value napiValue = nullptr;
257    bool result = true;
258    bool enable = GetBoolFromOption(env, info);
259    g_hiperfRecordOption->SetNoInherit(enable);
260
261    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
262    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
263    return napiValue;
264}
265static napi_value SetSelectPids(napi_env env, napi_callback_info info)
266{
267    napi_value napiValue = nullptr;
268    bool result = true;
269    std::string option = GetJsStringFromOption(env, info);
270    g_hiperfRecordOption->SetSelectPids(StringSplitToInt(option));
271
272    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
273    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
274    return napiValue;
275};
276static napi_value SetCallStackSamplingConfigs(napi_env env, napi_callback_info info)
277{
278    napi_value napiValue = nullptr;
279    bool result = true;
280    uint32_t option = GetUintFromOption(env, info);
281    g_hiperfRecordOption->SetCallStackSamplingConfigs(option);
282
283    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
284    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
285    return napiValue;
286}
287
288static napi_value SetSelectTids(napi_env env, napi_callback_info info)
289{
290    napi_value napiValue = nullptr;
291    bool result = true;
292    std::string option = GetJsStringFromOption(env, info);
293    g_hiperfRecordOption->SetSelectTids(StringSplitToInt(option));
294
295    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
296    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
297    return napiValue;
298}
299
300static napi_value SetExcludePerf(napi_env env, napi_callback_info info)
301{
302    napi_value napiValue = nullptr;
303    bool result = true;
304    bool enable = GetBoolFromOption(env, info);
305    g_hiperfRecordOption->SetExcludePerf(enable);
306
307    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
308    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
309    return napiValue;
310}
311
312static napi_value SetCpuPercent(napi_env env, napi_callback_info info)
313{
314    napi_value napiValue = nullptr;
315    bool result = true;
316    uint32_t option = GetUintFromOption(env, info);
317    g_hiperfRecordOption->SetCpuPercent(option);
318
319    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
320    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
321    return napiValue;
322}
323
324static napi_value SetOffCPU(napi_env env, napi_callback_info info)
325{
326    napi_value napiValue = nullptr;
327    bool result = true;
328    bool enable = GetBoolFromOption(env, info);
329    g_hiperfRecordOption->SetOffCPU(enable);
330
331    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
332    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
333    return napiValue;
334}
335
336static napi_value SetCallGraph(napi_env env, napi_callback_info info)
337{
338    napi_value napiValue = nullptr;
339    bool result = true;
340    std::string option = GetJsStringFromOption(env, info);
341    g_hiperfRecordOption->SetCallGraph((option));
342
343    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
344    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
345    return napiValue;
346}
347
348static napi_value SetDelayUnwind(napi_env env, napi_callback_info info)
349{
350    napi_value napiValue = nullptr;
351    bool result = true;
352    bool enable = GetBoolFromOption(env, info);
353    g_hiperfRecordOption->SetDelayUnwind(enable);
354
355    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
356    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
357    return napiValue;
358}
359
360static napi_value SetDisableUnwind(napi_env env, napi_callback_info info)
361{
362    napi_value napiValue = nullptr;
363    bool result = true;
364    bool enable = GetBoolFromOption(env, info);
365    g_hiperfRecordOption->SetDisableUnwind(enable);
366
367    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
368    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
369    return napiValue;
370}
371
372static napi_value SetDisableCallstackMerge(napi_env env, napi_callback_info info)
373{
374    napi_value napiValue = nullptr;
375    bool result = true;
376    bool enable = GetBoolFromOption(env, info);
377    g_hiperfRecordOption->SetDisableCallstackMerge(enable);
378
379    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
380    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
381    return napiValue;
382}
383
384static napi_value SetSymbolDir(napi_env env, napi_callback_info info)
385{
386    napi_value napiValue = nullptr;
387    bool result = true;
388    std::string option = GetJsStringFromOption(env, info);
389    g_hiperfRecordOption->SetSymbolDir(option);
390
391    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
392    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
393    return napiValue;
394}
395
396static napi_value SetDataLimit(napi_env env, napi_callback_info info)
397{
398    napi_value napiValue = nullptr;
399    bool result = true;
400    std::string option = GetJsStringFromOption(env, info);
401    g_hiperfRecordOption->SetDataLimit(option);
402
403    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
404    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
405    return napiValue;
406}
407
408static napi_value SetAppPackage(napi_env env, napi_callback_info info)
409{
410    napi_value napiValue = nullptr;
411    bool result = true;
412    std::string option = GetJsStringFromOption(env, info);
413    g_hiperfRecordOption->SetAppPackage(option);
414
415    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
416    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
417    return napiValue;
418}
419
420static napi_value SetClockId(napi_env env, napi_callback_info info)
421{
422    napi_value napiValue = nullptr;
423    bool result = true;
424    std::string option = GetJsStringFromOption(env, info);
425    g_hiperfRecordOption->SetClockId(option);
426
427    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
428    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
429    return napiValue;
430}
431
432static napi_value SetVecBranchSampleTypes(napi_env env, napi_callback_info info)
433{
434    napi_value napiValue = nullptr;
435    bool result = true;
436    std::string option = GetJsStringFromOption(env, info);
437    g_hiperfRecordOption->SetVecBranchSampleTypes(StringSplit(option));
438
439    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
440    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
441    return napiValue;
442}
443
444static napi_value SetMmapPages(napi_env env, napi_callback_info info)
445{
446    napi_value napiValue = nullptr;
447    bool result = true;
448    uint32_t option = GetUintFromOption(env, info);
449    g_hiperfRecordOption->SetMmapPages(option);
450
451    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
452    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
453    return napiValue;
454}
455
456static napi_value GetOptionVecString(napi_env env, napi_callback_info info)
457{
458    napi_value napiValue = nullptr;
459    const std::vector<std::string> items = g_hiperfRecordOption->GetOptionVecString();
460    std::string result;
461    const std::string split = ",";
462    for (auto item : items) {
463        if (!result.empty())
464            result.append(split);
465        result.append(item);
466    }
467    if (result.empty()) {
468        result.append("<empty>");
469    }
470
471    NAPI_CALL(env, napi_create_string_utf8(env, result.c_str(), result.size(), &napiValue));
472
473    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}s", result.c_str());
474    return napiValue;
475}
476
477static napi_value StartWithOption(napi_env env, napi_callback_info info)
478{
479    napi_value napiValue = nullptr;
480
481    // for js api , we always use hilog
482    g_hiperfClient->EnableHilog();
483
484    bool result = g_hiperfClient->Setup(g_hiperfRecordOption->GetOutputFileName());
485    if (result) {
486        const HiperfClient::RecordOption *option = g_hiperfRecordOption.get();
487        result = g_hiperfClient->Start(*option);
488    }
489    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
490    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
491    return napiValue;
492}
493
494static napi_value Start(napi_env env, napi_callback_info info)
495{
496    napi_value napiValue = nullptr;
497
498    // for js api , we always use hilog
499    g_hiperfClient->EnableHilog();
500
501    bool result = g_hiperfClient->Start();
502
503    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
504    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
505    return napiValue;
506}
507
508static napi_value Setup(napi_env env, napi_callback_info info)
509{
510    napi_value napiValue = nullptr;
511
512    std::string outputPath = GetJsStringFromOption(env, info);
513
514    // for js api , we always use hilog
515    g_hiperfClient->EnableHilog();
516    bool result = g_hiperfClient->Setup(outputPath);
517
518    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
519    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
520    return napiValue;
521}
522
523static napi_value IsReady(napi_env env, napi_callback_info info)
524{
525    napi_value napiValue = nullptr;
526    bool result = g_hiperfClient->IsReady();
527
528    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
529
530    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
531    return napiValue;
532}
533
534static napi_value Stop(napi_env env, napi_callback_info info)
535{
536    napi_value napiValue = nullptr;
537    bool result = g_hiperfClient->Stop();
538
539    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
540
541    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
542    return napiValue;
543}
544
545static napi_value Pause(napi_env env, napi_callback_info info)
546{
547    napi_value napiValue = nullptr;
548    bool result = g_hiperfClient->Pause();
549
550    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
551
552    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
553    return napiValue;
554}
555
556static napi_value Resume(napi_env env, napi_callback_info info)
557{
558    napi_value napiValue = nullptr;
559    bool result = g_hiperfClient->Resume();
560
561    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
562
563    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
564    return napiValue;
565}
566
567static napi_value GetOutputDir(napi_env env, napi_callback_info info)
568{
569    napi_value napiValue = nullptr;
570    std::string result = g_hiperfClient->GetOutputDir();
571
572    NAPI_CALL(env, napi_create_string_utf8(env, result.c_str(), result.size(), &napiValue));
573
574    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}s", result.c_str());
575    return napiValue;
576}
577
578static napi_value GetCommandPath(napi_env env, napi_callback_info info)
579{
580    napi_value napiValue = nullptr;
581    std::string result = g_hiperfClient->GetCommandPath();
582
583    NAPI_CALL(env, napi_create_string_utf8(env, result.c_str(), result.size(), &napiValue));
584
585    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}s", result.c_str());
586    return napiValue;
587}
588
589static napi_value GetOutputPerfDataPath(napi_env env, napi_callback_info info)
590{
591    napi_value napiValue = nullptr;
592    std::string result = g_hiperfClient->GetOutputPerfDataPath();
593
594    NAPI_CALL(env, napi_create_string_utf8(env, result.c_str(), result.size(), &napiValue));
595
596    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}s", result.c_str());
597    return napiValue;
598}
599
600static napi_value SetDebugMode(napi_env env, napi_callback_info info)
601{
602    napi_value napiValue = nullptr;
603    bool result = true;
604
605    g_hiperfClient->SetDebugMode();
606
607    NAPI_CALL(env, napi_create_int32(env, result, &napiValue));
608
609    HIPERF_HILOGD(MODULE_JS_NAPI, "%{public}d", result);
610    return napiValue;
611}
612} // namespace HiperfClient
613} // namespace HiPerf
614} // namespace Developtools
615} // namespace OHOS
616
617using namespace OHOS::Developtools::HiPerf::HiperfClient;
618
619EXTERN_C_START
620/*
621 * function for module exports
622 */
623static napi_value HiperfClientInit(napi_env env, napi_value exports)
624{
625    HIPERF_HILOGD(MODULE_JS_NAPI, "enter");
626
627    napi_property_descriptor desc[] = {
628        DECLARE_NAPI_FUNCTION("isReady", IsReady),
629        DECLARE_NAPI_FUNCTION("setup", Setup),
630        DECLARE_NAPI_FUNCTION("start", Start),
631        DECLARE_NAPI_FUNCTION("stop", Stop),
632        DECLARE_NAPI_FUNCTION("pause", Pause),
633        DECLARE_NAPI_FUNCTION("resume", Resume),
634        DECLARE_NAPI_FUNCTION("getOutputDir", GetOutputDir),
635        DECLARE_NAPI_FUNCTION("getOutputPerfDataPath", GetOutputPerfDataPath),
636        DECLARE_NAPI_FUNCTION("getCommandPath", GetCommandPath),
637        DECLARE_NAPI_FUNCTION("setDebugMode", SetDebugMode),
638        // Option:
639        DECLARE_NAPI_FUNCTION("startWithOption", StartWithOption),
640        DECLARE_NAPI_FUNCTION("resetOption", ResetOption),
641        DECLARE_NAPI_FUNCTION("setOutputFilename", SetOutputFilename),
642        DECLARE_NAPI_FUNCTION("getOutputFileName", GetOutputFileName),
643        DECLARE_NAPI_FUNCTION("setTargetSystemWide", SetTargetSystemWide),
644        DECLARE_NAPI_FUNCTION("setCompressData", SetCompressData),
645        DECLARE_NAPI_FUNCTION("setSelectCpus", SetSelectCpus),
646        DECLARE_NAPI_FUNCTION("setTimeStopSec", SetTimeStopSec),
647        DECLARE_NAPI_FUNCTION("setFrequency", SetFrequency),
648        DECLARE_NAPI_FUNCTION("setPeriod", SetPeriod),
649        DECLARE_NAPI_FUNCTION("setSelectEvents", SetSelectEvents),
650        DECLARE_NAPI_FUNCTION("setSelectGroups", SetSelectGroups),
651        DECLARE_NAPI_FUNCTION("setNoInherit", SetNoInherit),
652        DECLARE_NAPI_FUNCTION("setSelectPids", SetSelectPids),
653        DECLARE_NAPI_FUNCTION("setCallStackSamplingConfigs", SetCallStackSamplingConfigs),
654        DECLARE_NAPI_FUNCTION("setSelectTids", SetSelectTids),
655        DECLARE_NAPI_FUNCTION("setExcludePerf", SetExcludePerf),
656        DECLARE_NAPI_FUNCTION("setCpuPercent", SetCpuPercent),
657        DECLARE_NAPI_FUNCTION("setOffCPU", SetOffCPU),
658        DECLARE_NAPI_FUNCTION("setCallGraph", SetCallGraph),
659        DECLARE_NAPI_FUNCTION("setDelayUnwind", SetDelayUnwind),
660        DECLARE_NAPI_FUNCTION("setDisableUnwind", SetDisableUnwind),
661        DECLARE_NAPI_FUNCTION("setDisableCallstackMerge", SetDisableCallstackMerge),
662        DECLARE_NAPI_FUNCTION("setSymbolDir", SetSymbolDir),
663        DECLARE_NAPI_FUNCTION("setDataLimit", SetDataLimit),
664        DECLARE_NAPI_FUNCTION("setAppPackage", SetAppPackage),
665        DECLARE_NAPI_FUNCTION("setClockId", SetClockId),
666        DECLARE_NAPI_FUNCTION("setVecBranchSampleTypes", SetVecBranchSampleTypes),
667        DECLARE_NAPI_FUNCTION("setMmapPages", SetMmapPages),
668        DECLARE_NAPI_FUNCTION("getOptionVecString", GetOptionVecString),
669    };
670    NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
671    HIPERF_HILOGD(MODULE_JS_NAPI, "exit");
672    return exports;
673}
674EXTERN_C_END
675
676/*
677 * Module definition
678 */
679static napi_module g_module = {
680    .nm_version = 1,
681    .nm_flags = 0,
682    .nm_filename = nullptr,
683    .nm_register_func = HiperfClientInit,
684    .nm_modname = "hiperf",
685    .nm_priv = ((void *)0),
686    .reserved = {0},
687};
688
689/*
690 * Module registration
691 */
692extern "C" __attribute__((constructor)) void RegisterModule(void)
693{
694    napi_module_register(&g_module);
695}
696