1 /*
2 * Copyright (c) 2024 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
16 #include "c/abckit.h"
17 #include "c/extensions/arkts/metadata_arkts.h"
18 #include "c/metadata_core.h"
19 #include "c/ir_core.h"
20 #include "c/statuses.h"
21
22 #include <iostream>
23 #include <functional>
24
25 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
26 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
27 static auto g_implArkI = AbckitGetArktsInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
28 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
29 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
30
TransformMethod(AbckitCoreFunction * method)31 static void TransformMethod(AbckitCoreFunction *method)
32 {
33 if (g_implI->moduleGetTarget(g_implI->functionGetModule(method)) == ABCKIT_TARGET_ARK_TS_V2) {
34 auto *arktsMethod = g_implArkI->coreFunctionToArktsFunction(method);
35 if (g_implArkI->functionIsNative(arktsMethod)) {
36 return;
37 }
38 }
39 AbckitGraph *graph = g_implI->createGraphFromFunction(method);
40 if (g_impl->getLastError() != ABCKIT_STATUS_NO_ERROR) {
41 return;
42 }
43 g_implM->functionSetGraph(method, graph);
44 g_impl->destroyGraph(graph);
45 }
46
EnumerateAllMethodsInModule(AbckitFile * file,std::function<bool (AbckitCoreNamespace *)> & cbNamespace,std::function<bool (AbckitCoreClass *)> & cbClass,std::function<bool (AbckitCoreFunction *)> & cbFunc,bool & hasError)47 static void EnumerateAllMethodsInModule(AbckitFile *file, std::function<bool(AbckitCoreNamespace *)> &cbNamespace,
48 std::function<bool(AbckitCoreClass *)> &cbClass,
49 std::function<bool(AbckitCoreFunction *)> &cbFunc, bool &hasError)
50 {
51 std::function<bool(AbckitCoreModule *)> cbModule = [&](AbckitCoreModule *m) {
52 g_implI->moduleEnumerateNamespaces(m, &cbNamespace, [](AbckitCoreNamespace *n, void *cb) {
53 return (*reinterpret_cast<std::function<bool(AbckitCoreNamespace *)> *>(cb))(n);
54 });
55 g_implI->moduleEnumerateClasses(m, &cbClass, [](AbckitCoreClass *c, void *cb) {
56 return (*reinterpret_cast<std::function<bool(AbckitCoreClass *)> *>(cb))(c);
57 });
58 g_implI->moduleEnumerateTopLevelFunctions(m, &cbFunc, [](AbckitCoreFunction *f, void *cb) {
59 return (*reinterpret_cast<std::function<bool(AbckitCoreFunction *)> *>(cb))(f);
60 });
61 return !hasError;
62 };
63
64 g_implI->fileEnumerateModules(file, &cbModule, [](AbckitCoreModule *m, void *cb) {
65 return (*reinterpret_cast<std::function<bool(AbckitCoreModule *)> *>(cb))(m);
66 });
67 }
68
Entry(AbckitFile * file)69 extern "C" int Entry(AbckitFile *file)
70 {
71 bool hasError = false;
72
73 std::function<bool(AbckitCoreClass *)> cbClass;
74
75 std::function<bool(AbckitCoreFunction *)> cbFunc = [&](AbckitCoreFunction *f) {
76 g_implI->functionEnumerateNestedFunctions(f, &cbFunc, [](AbckitCoreFunction *f, void *cb) {
77 return (*reinterpret_cast<std::function<bool(AbckitCoreFunction *)> *>(cb))(f);
78 });
79 g_implI->functionEnumerateNestedClasses(f, &cbClass, [](AbckitCoreClass *c, void *cb) {
80 return (*reinterpret_cast<std::function<bool(AbckitCoreClass *)> *>(cb))(c);
81 });
82
83 TransformMethod(f);
84 if (g_impl->getLastError() != ABCKIT_STATUS_NO_ERROR) {
85 hasError = true;
86 }
87
88 return !hasError;
89 };
90
91 cbClass = [&](AbckitCoreClass *c) {
92 g_implI->classEnumerateMethods(c, &cbFunc, [](AbckitCoreFunction *m, void *cb) {
93 return (*reinterpret_cast<std::function<bool(AbckitCoreFunction *)> *>(cb))(m);
94 });
95 return !hasError;
96 };
97
98 std::function<bool(AbckitCoreNamespace *)> cbNamespace = [&](AbckitCoreNamespace *n) {
99 g_implI->namespaceEnumerateNamespaces(n, &cbNamespace, [](AbckitCoreNamespace *n, void *cb) {
100 return (*reinterpret_cast<std::function<bool(AbckitCoreNamespace *)> *>(cb))(n);
101 });
102 g_implI->namespaceEnumerateClasses(n, &cbClass, [](AbckitCoreClass *c, void *cb) {
103 return (*reinterpret_cast<std::function<bool(AbckitCoreClass *)> *>(cb))(c);
104 });
105 g_implI->namespaceEnumerateTopLevelFunctions(n, &cbFunc, [](AbckitCoreFunction *f, void *cb) {
106 return (*reinterpret_cast<std::function<bool(AbckitCoreFunction *)> *>(cb))(f);
107 });
108 return !hasError;
109 };
110
111 std::cout << "Stress plugin start" << std::endl;
112
113 EnumerateAllMethodsInModule(file, cbNamespace, cbClass, cbFunc, hasError);
114
115 std::cout << "Stress plugin end" << std::endl;
116
117 return hasError ? 1 : 0;
118 }
119