1#include "DataFormatters/FormatterBytecode.h"
2#include "lldb/Utility/StreamString.h"
3
4#include "gtest/gtest.h"
5
6using namespace lldb_private;
7using namespace lldb;
8using namespace FormatterBytecode;
9using llvm::StringRef;
10
11namespace {
12class FormatterBytecodeTest : public ::testing::Test {};
13
14bool Interpret(std::vector<uint8_t> code, DataStack &data) {
15 auto buf =
16 StringRef(reinterpret_cast<const char *>(code.data()), code.size());
17 std::vector<ControlStackElement> control({buf});
18 if (auto error = Interpret(control, data, sel: sel_summary)) {
19#ifndef NDEBUG
20 llvm::errs() << llvm::toString(E: std::move(error)) << '\n';
21#else
22 llvm::consumeError(std::move(error));
23#endif
24 return false;
25 }
26 return true;
27}
28
29} // namespace
30
31TEST_F(FormatterBytecodeTest, StackOps) {
32 {
33 DataStack data;
34 ASSERT_TRUE(Interpret({op_lit_uint, 23, op_dup, op_plus}, data));
35 ASSERT_EQ(data.Pop<uint64_t>(), 46u);
36 }
37 {
38 DataStack data;
39 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_drop}, data));
40 ASSERT_EQ(data.size(), 0u);
41 }
42 {
43 for (unsigned char i = 0; i < 3; ++i) {
44 DataStack data;
45
46 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_lit_uint, 2,
47 op_lit_uint, i, op_pick},
48 data));
49 ASSERT_EQ(data.Pop<uint64_t>(), i);
50 }
51 }
52 {
53 DataStack data;
54 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_over}, data));
55 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
56 }
57 {
58 DataStack data;
59 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_swap}, data));
60 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
61 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
62 }
63 {
64 DataStack data;
65 ASSERT_TRUE(Interpret(
66 {op_lit_uint, 0, op_lit_uint, 1, op_lit_uint, 2, op_rot}, data));
67 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
68 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
69 ASSERT_EQ(data.Pop<uint64_t>(), 2u);
70 }
71}
72
73TEST_F(FormatterBytecodeTest, ControlOps) {
74 {
75 DataStack data;
76 ASSERT_TRUE(
77 Interpret({op_lit_uint, 0, op_begin, 2, op_lit_uint, 42, op_if}, data));
78 ASSERT_EQ(data.size(), 0u);
79 }
80 {
81 DataStack data;
82 ASSERT_TRUE(
83 Interpret({op_lit_uint, 1, op_begin, 2, op_lit_uint, 42, op_if}, data));
84 ASSERT_EQ(data.Pop<uint64_t>(), 42u);
85 }
86 {
87 DataStack data;
88 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_begin, 2, op_lit_uint, 42,
89 op_begin, 2, op_lit_uint, 23, op_ifelse},
90 data));
91 ASSERT_EQ(data.Pop<uint64_t>(), 23u);
92 }
93 {
94 DataStack data;
95 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_begin, 2, op_lit_uint, 42,
96 op_begin, 2, op_lit_uint, 23, op_ifelse},
97 data));
98 ASSERT_EQ(data.Pop<uint64_t>(), 42u);
99 }
100 {
101 DataStack data;
102 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_begin, 3, op_lit_uint, 42,
103 op_return, op_if, op_lit_uint, 23},
104 data));
105 ASSERT_EQ(data.Pop<uint64_t>(), 42u);
106 }
107}
108
109TEST_F(FormatterBytecodeTest, ConversionOps) {
110 {
111 DataStack data(lldb::ValueObjectSP{});
112 ASSERT_TRUE(Interpret({op_is_null}, data));
113 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
114 }
115 {
116 DataStack data;
117 ASSERT_TRUE(Interpret({op_lit_uint, 1u, op_as_int}, data));
118 ASSERT_EQ(data.Pop<int64_t>(), 1);
119 }
120 {
121 DataStack data;
122 ASSERT_TRUE(Interpret({op_lit_int, 126, op_as_uint}, data));
123 ASSERT_EQ(data.Pop<uint64_t>(), ~1ULL);
124 }
125}
126
127TEST_F(FormatterBytecodeTest, ArithOps) {
128 {
129 DataStack data;
130 ASSERT_TRUE(Interpret({op_lit_uint, 2, op_lit_uint, 3, op_plus}, data));
131 ASSERT_EQ(data.Pop<uint64_t>(), 5u);
132 }
133 {
134 DataStack data;
135 ASSERT_TRUE(Interpret({op_lit_uint, 3, op_lit_uint, 2, op_minus}, data));
136 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
137 }
138 {
139 DataStack data;
140 ASSERT_TRUE(Interpret({op_lit_uint, 3, op_lit_uint, 2, op_mul}, data));
141 ASSERT_EQ(data.Pop<uint64_t>(), 6u);
142 }
143 {
144 DataStack data;
145 ASSERT_TRUE(Interpret({op_lit_uint, 6, op_lit_uint, 2, op_div}, data));
146 ASSERT_EQ(data.Pop<uint64_t>(), 3u);
147 }
148 {
149 DataStack data;
150 ASSERT_FALSE(Interpret({op_lit_uint, 23, op_lit_uint, 0, op_div}, data));
151 }
152 {
153 DataStack data;
154 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 2, op_shl}, data));
155 ASSERT_EQ(data.Pop<uint64_t>(), 4u);
156 }
157 {
158 DataStack data;
159 unsigned char minus_one = 127;
160 ASSERT_FALSE(
161 Interpret({op_lit_int, minus_one, op_lit_uint, 2, op_shl}, data));
162 unsigned char minus_two = 126;
163 ASSERT_TRUE(
164 Interpret({op_lit_int, minus_two, op_lit_uint, 1, op_shr}, data));
165 ASSERT_EQ(data.Pop<int64_t>(), -1);
166 }
167 {
168 DataStack data;
169 ASSERT_FALSE(Interpret({op_lit_uint, 1, op_lit_uint, 65, op_shl}, data));
170 ASSERT_FALSE(Interpret({op_lit_uint, 1, op_lit_uint, 65, op_shr}, data));
171 }
172 {
173 DataStack data;
174 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_and}, data));
175 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
176 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_and}, data));
177 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
178 }
179 {
180 DataStack data;
181 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_or}, data));
182 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
183 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_or}, data));
184 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
185 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_or}, data));
186 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
187 }
188 {
189 DataStack data;
190 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_xor}, data));
191 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
192 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_xor}, data));
193 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
194 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_xor}, data));
195 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
196 }
197 {
198 DataStack data;
199 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_not}, data));
200 ASSERT_EQ(data.Pop<uint64_t>(), 0xffffffffffffffff);
201 }
202 {
203 DataStack data;
204 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_eq}, data));
205 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
206 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_eq}, data));
207 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
208 }
209 {
210 DataStack data;
211 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_neq}, data));
212 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
213 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_neq}, data));
214 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
215 }
216 {
217 DataStack data;
218 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_lt}, data));
219 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
220 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_lt}, data));
221 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
222 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_lt}, data));
223 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
224 }
225 {
226 DataStack data;
227 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_gt}, data));
228 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
229 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_gt}, data));
230 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
231 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_gt}, data));
232 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
233 }
234 {
235 DataStack data;
236 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_le}, data));
237 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
238 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_le}, data));
239 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
240 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_le}, data));
241 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
242 }
243 {
244 DataStack data;
245 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_ge}, data));
246 ASSERT_EQ(data.Pop<uint64_t>(), 0u);
247 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_ge}, data));
248 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
249 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_ge}, data));
250 ASSERT_EQ(data.Pop<uint64_t>(), 1u);
251 }
252}
253
254TEST_F(FormatterBytecodeTest, CallOps) {
255 {
256 DataStack data;
257 data.Push(el: std::string{"hello"});
258 ASSERT_TRUE(Interpret({op_lit_selector, sel_strlen, op_call}, data));
259 ASSERT_EQ(data.Pop<uint64_t>(), 5u);
260 }
261 {
262 DataStack data;
263 data.Push(el: std::string{"A"});
264 data.Push(el: std::string{"B"});
265 data.Push(el: std::string{"{1}{0}"});
266 ASSERT_TRUE(Interpret({op_lit_selector, sel_fmt, op_call}, data));
267 ASSERT_EQ(data.Pop<std::string>(), "BA");
268 }
269 {
270 DataStack data;
271 data.Push(el: std::string{"{0}"});
272 ASSERT_FALSE(Interpret({op_lit_selector, sel_fmt, op_call}, data));
273 }
274}
275

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp