275 lines · cpp
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_summary)) {19#ifndef NDEBUG20 llvm::errs() << llvm::toString(std::move(error)) << '\n';21#else22 llvm::consumeError(std::move(error));23#endif24 return false;25 }26 return true;27}28 29} // namespace30 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(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(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");268 }269 {270 DataStack data;271 data.Push(std::string{"{0}"});272 ASSERT_FALSE(Interpret({op_lit_selector, sel_fmt, op_call}, data));273 }274}275