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 "libabckit/include/c/abckit.h"
17 #include "adapter_static/ir_static.h"
18 #include "libabckit/include/c/metadata_core.h"
19 #include "libabckit/include/c/ir_core.h"
20 #include "libabckit/include/c/isa/isa_dynamic.h"
21
22 #include "helpers/helpers.h"
23 #include "helpers/helpers_runtime.h"
24
25 #include <gtest/gtest.h>
26
27 namespace libabckit::test {
28
29 class AbckitScenarioTest : public ::testing::Test {};
30
31 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35 static auto g_dynG = AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0);
36
37 struct UserData {
38 AbckitString *print = nullptr;
39 };
40
TransformIr(AbckitGraph * graph,UserData * userData)41 static void TransformIr(AbckitGraph *graph, UserData *userData)
42 {
43 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
44 AbckitBasicBlock *endBB = g_implG->gGetEndBasicBlock(graph);
45 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
46 AbckitBasicBlock *bb = succBBs[0];
47 AbckitInst *initInst = g_implG->bbGetFirstInst(bb);
48 AbckitInst *prevRetInst = g_implG->iGetPrev(g_implG->bbGetLastInst(bb));
49
50 AbckitBasicBlock *tryBegin =
51 g_implG->bbSplitBlockAfterInstruction(g_implG->iGetBasicBlock(initInst), initInst, true);
52 AbckitBasicBlock *tryEnd =
53 g_implG->bbSplitBlockAfterInstruction(g_implG->iGetBasicBlock(prevRetInst), prevRetInst, true);
54
55 // Fill catchBlock
56 AbckitBasicBlock *catchBlock = g_implG->bbCreateEmpty(graph);
57 AbckitInst *catchPhi = g_implG->bbCreateCatchPhi(catchBlock, 0);
58 AbckitInst *print = g_dynG->iCreateTryldglobalbyname(graph, userData->print);
59 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
60 g_implG->bbAddInstBack(catchBlock, print);
61 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
62 AbckitInst *callArg = g_dynG->iCreateCallarg1(graph, print, catchPhi);
63 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
64 g_implG->bbAddInstBack(catchBlock, callArg);
65
66 AbckitBasicBlock *epilogueBB = helpers::BBgetPredBlocks(endBB)[0];
67 AbckitInst *retInst = g_implG->bbGetLastInst(epilogueBB);
68 AbckitInst *firstPhiInput = g_implG->iGetInput(retInst, 0);
69 AbckitInst *secondPhiInput = g_dynG->iCreateLdfalse(graph);
70 g_implG->bbAddInstBack(bb, secondPhiInput);
71 AbckitInst *phiInst = g_implG->bbCreatePhi(epilogueBB, 2, firstPhiInput, secondPhiInput);
72 g_implG->iSetInput(retInst, phiInst, 0);
73
74 g_implG->gInsertTryCatch(tryBegin, tryEnd, catchBlock, catchBlock);
75 }
76
77 // Test: test-kind=scenario, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(AbckitScenarioTest,LibAbcKitTestDynamicAddTryCatch)78 TEST_F(AbckitScenarioTest, LibAbcKitTestDynamicAddTryCatch)
79 {
80 auto output =
81 helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "scenarios/add_try_catch/dynamic/add_try_catch.abc", "add_try_catch");
82 EXPECT_TRUE(helpers::Match(output, "THROW\n"));
83
84 helpers::TransformMethod(
85 ABCKIT_ABC_DIR "scenarios/add_try_catch/dynamic/add_try_catch.abc",
86 ABCKIT_ABC_DIR "scenarios/add_try_catch/dynamic/add_try_catch_modified.abc", "run",
87 [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *graph) {
88 UserData uData {};
89 uData.print = g_implM->createString(file, "print", strlen("print"));
90 TransformIr(graph, &uData);
91 },
92 []([[maybe_unused]] AbckitGraph *graph) {});
93
94 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "scenarios/add_try_catch/dynamic/add_try_catch_modified.abc",
95 "add_try_catch");
96 EXPECT_TRUE(helpers::Match(output,
97 "THROW\n"
98 "Error: DUMMY_ERROR\n"
99 "false\n"));
100 }
101
102 } // namespace libabckit::test
103