1 #include "DataFormatters/FormatterBytecode.h"
2 #include "lldb/Utility/StreamString.h"
4 #include "gtest/gtest.h"
6 using namespace lldb_private
;
8 using namespace FormatterBytecode
;
12 class FormatterBytecodeTest
: public ::testing::Test
{};
14 bool Interpret(std::vector
<uint8_t> code
, DataStack
&data
) {
16 StringRef(reinterpret_cast<const char *>(code
.data()), code
.size());
17 std::vector
<ControlStackElement
> control({buf
});
18 if (auto error
= Interpret(control
, data
, sel_summary
)) {
20 llvm::errs() << llvm::toString(std::move(error
)) << '\n';
22 llvm::consumeError(std::move(error
));
31 TEST_F(FormatterBytecodeTest
, StackOps
) {
34 ASSERT_TRUE(Interpret({op_lit_uint
, 23, op_dup
, op_plus
}, data
));
35 ASSERT_EQ(data
.Pop
<uint64_t>(), 46u);
39 ASSERT_TRUE(Interpret({op_lit_uint
, 0, op_drop
}, data
));
40 ASSERT_EQ(data
.size(), 0u);
43 for (unsigned char i
= 0; i
< 3; ++i
) {
46 ASSERT_TRUE(Interpret({op_lit_uint
, 0, op_lit_uint
, 1, op_lit_uint
, 2,
47 op_lit_uint
, i
, op_pick
},
49 ASSERT_EQ(data
.Pop
<uint64_t>(), i
);
54 ASSERT_TRUE(Interpret({op_lit_uint
, 0, op_lit_uint
, 1, op_over
}, data
));
55 ASSERT_EQ(data
.Pop
<uint64_t>(), 0u);
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);
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);
73 TEST_F(FormatterBytecodeTest
, ControlOps
) {
77 Interpret({op_lit_uint
, 0, op_begin
, 2, op_lit_uint
, 42, op_if
}, data
));
78 ASSERT_EQ(data
.size(), 0u);
83 Interpret({op_lit_uint
, 1, op_begin
, 2, op_lit_uint
, 42, op_if
}, data
));
84 ASSERT_EQ(data
.Pop
<uint64_t>(), 42u);
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
},
91 ASSERT_EQ(data
.Pop
<uint64_t>(), 23u);
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
},
98 ASSERT_EQ(data
.Pop
<uint64_t>(), 42u);
102 ASSERT_TRUE(Interpret({op_lit_uint
, 1, op_begin
, 3, op_lit_uint
, 42,
103 op_return
, op_if
, op_lit_uint
, 23},
105 ASSERT_EQ(data
.Pop
<uint64_t>(), 42u);
109 TEST_F(FormatterBytecodeTest
, ConversionOps
) {
111 DataStack
data(lldb::ValueObjectSP
{});
112 ASSERT_TRUE(Interpret({op_is_null
}, data
));
113 ASSERT_EQ(data
.Pop
<uint64_t>(), 1u);
117 ASSERT_TRUE(Interpret({op_lit_uint
, 1u, op_as_int
}, data
));
118 ASSERT_EQ(data
.Pop
<int64_t>(), 1);
122 ASSERT_TRUE(Interpret({op_lit_int
, 126, op_as_uint
}, data
));
123 ASSERT_EQ(data
.Pop
<uint64_t>(), ~1ULL);
127 TEST_F(FormatterBytecodeTest
, ArithOps
) {
130 ASSERT_TRUE(Interpret({op_lit_uint
, 2, op_lit_uint
, 3, op_plus
}, data
));
131 ASSERT_EQ(data
.Pop
<uint64_t>(), 5u);
135 ASSERT_TRUE(Interpret({op_lit_uint
, 3, op_lit_uint
, 2, op_minus
}, data
));
136 ASSERT_EQ(data
.Pop
<uint64_t>(), 1u);
140 ASSERT_TRUE(Interpret({op_lit_uint
, 3, op_lit_uint
, 2, op_mul
}, data
));
141 ASSERT_EQ(data
.Pop
<uint64_t>(), 6u);
145 ASSERT_TRUE(Interpret({op_lit_uint
, 6, op_lit_uint
, 2, op_div
}, data
));
146 ASSERT_EQ(data
.Pop
<uint64_t>(), 3u);
150 ASSERT_FALSE(Interpret({op_lit_uint
, 23, op_lit_uint
, 0, op_div
}, data
));
154 ASSERT_TRUE(Interpret({op_lit_uint
, 1, op_lit_uint
, 2, op_shl
}, data
));
155 ASSERT_EQ(data
.Pop
<uint64_t>(), 4u);
159 unsigned char minus_one
= 127;
161 Interpret({op_lit_int
, minus_one
, op_lit_uint
, 2, op_shl
}, data
));
162 unsigned char minus_two
= 126;
164 Interpret({op_lit_int
, minus_two
, op_lit_uint
, 1, op_shr
}, data
));
165 ASSERT_EQ(data
.Pop
<int64_t>(), -1);
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
));
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);
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);
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);
199 ASSERT_TRUE(Interpret({op_lit_uint
, 0, op_not
}, data
));
200 ASSERT_EQ(data
.Pop
<uint64_t>(), 0xffffffffffffffff);
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);
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);
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);
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);
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);
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);
254 TEST_F(FormatterBytecodeTest
, CallOps
) {
257 data
.Push(std::string
{"hello"});
258 ASSERT_TRUE(Interpret({op_lit_selector
, sel_strlen
, op_call
}, data
));
259 ASSERT_EQ(data
.Pop
<uint64_t>(), 5u);
263 data
.Push(std::string
{"A"});
264 data
.Push(std::string
{"B"});
265 data
.Push(std::string
{"{1}{0}"});
266 ASSERT_TRUE(Interpret({op_lit_selector
, sel_fmt
, op_call
}, data
));
267 ASSERT_EQ(data
.Pop
<std::string
>(), "BA");
271 data
.Push(std::string
{"{0}"});
272 ASSERT_FALSE(Interpret({op_lit_selector
, sel_fmt
, op_call
}, data
));