1 /**
2 * Copyright (c) 2021-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 "absint/reg_context.h"
17 #include "absint/exec_context.h"
18
19 #include "public_internal.h"
20 #include "jobs/service.h"
21 #include "type/type_system.h"
22 #include "value/abstract_typed_value.h"
23
24 #include "util/lazy.h"
25 #include "util/tests/verifier_test.h"
26
27 #include <gtest/gtest.h>
28
29 #include <functional>
30
31 // NOLINTBEGIN(readability-magic-numbers,cppcoreguidelines-pro-bounds-pointer-arithmetic)
32
33 namespace ark::verifier::test {
34
ProcessAbsIntExecContext(ExecContext & execCtx,std::array<const uint8_t *,6> & cp,RegContext & ctx2,RegContext & ctx3,uint8_t const instructions[128U])35 void ProcessAbsIntExecContext(ExecContext &execCtx, std::array<const uint8_t *, 6> &cp, RegContext &ctx2,
36 RegContext &ctx3, uint8_t const instructions[128U]) // NOLINT(modernize-avoid-c-arrays)
37 {
38 const uint8_t *ep = &instructions[0];
39 EntryPointType ept;
40
41 execCtx.CurrentRegContext() = ctx2;
42 while (ep != cp[0U]) {
43 execCtx.StoreCurrentRegContextForAddr(ep++);
44 }
45 execCtx.StoreCurrentRegContextForAddr(ep++);
46
47 execCtx.CurrentRegContext() = ctx3;
48 while (ep != cp[1U]) {
49 execCtx.StoreCurrentRegContextForAddr(ep++);
50 }
51 execCtx.StoreCurrentRegContextForAddr(ep);
52
53 execCtx.CurrentRegContext() = ctx2;
54 while (ep != cp[2U]) {
55 execCtx.StoreCurrentRegContextForAddr(ep++);
56 }
57 execCtx.StoreCurrentRegContextForAddr(ep++);
58
59 execCtx.CurrentRegContext() = ctx3;
60 while (ep != cp[3U]) {
61 execCtx.StoreCurrentRegContextForAddr(ep++);
62 }
63 execCtx.StoreCurrentRegContextForAddr(ep++);
64
65 execCtx.CurrentRegContext() = ctx2;
66 while (ep != cp[4U]) {
67 execCtx.StoreCurrentRegContextForAddr(ep++);
68 }
69 execCtx.StoreCurrentRegContextForAddr(ep++);
70
71 execCtx.CurrentRegContext() = ctx3;
72 while (ep != cp[5U]) {
73 execCtx.StoreCurrentRegContextForAddr(ep++);
74 }
75 execCtx.StoreCurrentRegContextForAddr(ep++);
76
77 execCtx.GetEntryPointForChecking(&ep, &ept);
78
79 execCtx.GetEntryPointForChecking(&ep, &ept);
80
81 auto status = execCtx.GetEntryPointForChecking(&ep, &ept);
82 EXPECT_EQ(status, ExecContext::Status::ALL_DONE);
83 }
84
TEST_F(VerifierTest,AbsIntExecContext)85 TEST_F(VerifierTest, AbsIntExecContext)
86 {
87 using Builtin = Type::Builtin;
88 auto *config = NewConfig();
89 RuntimeOptions runtimeOpts;
90 Runtime::Create(runtimeOpts);
91 auto *service = CreateService(config, Runtime::GetCurrent()->GetInternalAllocator(),
92 Runtime::GetCurrent()->GetClassLinker(), "");
93 TypeSystem typeSystem(service->verifierService);
94 Variables variables;
95
96 auto i16 = Type {Builtin::I16};
97 auto i32 = Type {Builtin::I32};
98
99 auto u16 = Type {Builtin::U16};
100
101 auto nv = [&variables] { return variables.NewVar(); };
102
103 AbstractTypedValue av1 {i16, nv()};
104 AbstractTypedValue av2 {i32, nv()};
105 AbstractTypedValue av3 {u16, nv()};
106
107 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
108 uint8_t instructions[128U];
109
110 ExecContext execCtx {&instructions[0], &instructions[127U], &typeSystem};
111
112 std::array<const uint8_t *, 6> cp = {&instructions[8U], &instructions[17U], &instructions[23U],
113 &instructions[49U], &instructions[73U], &instructions[103U]};
114
115 execCtx.SetCheckPoints(ConstLazyFetch(cp));
116
117 // 1 1 1 1 1 1
118 // C I C I C I
119 // E E
120
121 RegContext ctx1;
122 RegContext ctx2;
123 RegContext ctx3;
124
125 ctx1[-1] = av1;
126 ctx1[0] = av2;
127
128 ctx2[0] = av1; // compat with 1
129
130 ctx3[-1] = av3; // incompat with 1
131
132 execCtx.CurrentRegContext() = ctx1;
133
134 execCtx.StoreCurrentRegContextForAddr(cp[0U]);
135 execCtx.StoreCurrentRegContextForAddr(cp[1U]);
136 execCtx.StoreCurrentRegContextForAddr(cp[2U]);
137 execCtx.StoreCurrentRegContextForAddr(cp[3U]);
138 execCtx.StoreCurrentRegContextForAddr(cp[4U]);
139 execCtx.StoreCurrentRegContextForAddr(cp[5U]);
140
141 execCtx.AddEntryPoint(cp[1U], EntryPointType::METHOD_BODY);
142 execCtx.AddEntryPoint(cp[4U], EntryPointType::METHOD_BODY);
143
144 ProcessAbsIntExecContext(execCtx, cp, ctx2, ctx3, instructions);
145
146 DestroyService(service, false);
147 DestroyConfig(config);
148 }
149
150 } // namespace ark::verifier::test
151
152 // NOLINTEND(readability-magic-numbers,cppcoreguidelines-pro-bounds-pointer-arithmetic)
153