1 #include "DataFormatters/FormatterBytecode.h" 2 #include "lldb/Utility/StreamString.h" 3 4 #include "gtest/gtest.h" 5 6 using namespace lldb_private; 7 using namespace lldb; 8 using namespace FormatterBytecode; 9 using llvm::StringRef; 10 11 namespace { 12 class FormatterBytecodeTest : public ::testing::Test {}; 13 14 bool 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 NDEBUG 20 llvm::errs() << llvm::toString(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 31 TEST_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 73 TEST_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(lldb::ValueObjectSP{}); 102 ASSERT_TRUE(Interpret({op_is_null}, data)); 103 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 104 } 105 { 106 DataStack data; 107 ASSERT_TRUE(Interpret({op_lit_uint, 1u, op_as_int}, data)); 108 ASSERT_EQ(data.Pop<int64_t>(), 1); 109 } 110 { 111 DataStack data; 112 ASSERT_TRUE(Interpret({op_lit_int, 126, op_as_uint}, data)); 113 ASSERT_EQ(data.Pop<uint64_t>(), ~1ULL); 114 } 115 } 116 117 TEST_F(FormatterBytecodeTest, ArithOps) { 118 { 119 DataStack data; 120 ASSERT_TRUE(Interpret({op_lit_uint, 2, op_lit_uint, 3, op_plus}, data)); 121 ASSERT_EQ(data.Pop<uint64_t>(), 5u); 122 } 123 { 124 DataStack data; 125 ASSERT_TRUE(Interpret({op_lit_uint, 3, op_lit_uint, 2, op_minus}, data)); 126 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 127 } 128 { 129 DataStack data; 130 ASSERT_TRUE(Interpret({op_lit_uint, 3, op_lit_uint, 2, op_mul}, data)); 131 ASSERT_EQ(data.Pop<uint64_t>(), 6u); 132 } 133 { 134 DataStack data; 135 ASSERT_TRUE(Interpret({op_lit_uint, 6, op_lit_uint, 2, op_div}, data)); 136 ASSERT_EQ(data.Pop<uint64_t>(), 3u); 137 } 138 { 139 DataStack data; 140 ASSERT_FALSE(Interpret({op_lit_uint, 23, op_lit_uint, 0, op_div}, data)); 141 } 142 { 143 DataStack data; 144 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 2, op_shl}, data)); 145 ASSERT_EQ(data.Pop<uint64_t>(), 4u); 146 } 147 { 148 DataStack data; 149 unsigned char minus_one = 127; 150 ASSERT_TRUE( 151 Interpret({op_lit_int, minus_one, op_lit_uint, 2, op_shl}, data)); 152 ASSERT_EQ(data.Pop<int64_t>(), -4); 153 } 154 { 155 DataStack data; 156 ASSERT_FALSE(Interpret({op_lit_uint, 1, op_lit_uint, 65, op_shl}, data)); 157 ASSERT_FALSE(Interpret({op_lit_uint, 1, op_lit_uint, 65, op_shr}, data)); 158 } 159 { 160 DataStack data; 161 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_and}, data)); 162 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 163 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_and}, data)); 164 ASSERT_EQ(data.Pop<uint64_t>(), 0u); 165 } 166 { 167 DataStack data; 168 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_or}, data)); 169 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 170 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_or}, data)); 171 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 172 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_or}, data)); 173 ASSERT_EQ(data.Pop<uint64_t>(), 0u); 174 } 175 { 176 DataStack data; 177 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_xor}, data)); 178 ASSERT_EQ(data.Pop<uint64_t>(), 0u); 179 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_xor}, data)); 180 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 181 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_xor}, data)); 182 ASSERT_EQ(data.Pop<uint64_t>(), 0u); 183 } 184 { 185 DataStack data; 186 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_not}, data)); 187 ASSERT_EQ(data.Pop<uint64_t>(), 0xffffffffffffffff); 188 } 189 { 190 DataStack data; 191 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_eq}, data)); 192 ASSERT_EQ(data.Pop<uint64_t>(), 0u); 193 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_eq}, data)); 194 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 195 } 196 { 197 DataStack data; 198 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_neq}, data)); 199 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 200 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_neq}, data)); 201 ASSERT_EQ(data.Pop<uint64_t>(), 0u); 202 } 203 { 204 DataStack data; 205 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_lt}, data)); 206 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 207 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_lt}, data)); 208 ASSERT_EQ(data.Pop<uint64_t>(), 0u); 209 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_lt}, data)); 210 ASSERT_EQ(data.Pop<uint64_t>(), 0u); 211 } 212 { 213 DataStack data; 214 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_gt}, data)); 215 ASSERT_EQ(data.Pop<uint64_t>(), 0u); 216 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_gt}, data)); 217 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 218 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_gt}, data)); 219 ASSERT_EQ(data.Pop<uint64_t>(), 0u); 220 } 221 { 222 DataStack data; 223 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_le}, data)); 224 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 225 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_le}, data)); 226 ASSERT_EQ(data.Pop<uint64_t>(), 0u); 227 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_le}, data)); 228 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 229 } 230 { 231 DataStack data; 232 ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_ge}, data)); 233 ASSERT_EQ(data.Pop<uint64_t>(), 0u); 234 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_ge}, data)); 235 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 236 ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_ge}, data)); 237 ASSERT_EQ(data.Pop<uint64_t>(), 1u); 238 } 239 } 240 241 TEST_F(FormatterBytecodeTest, CallOps) { 242 { 243 DataStack data; 244 data.Push(std::string{"hello"}); 245 ASSERT_TRUE(Interpret({op_lit_selector, sel_strlen, op_call}, data)); 246 ASSERT_EQ(data.Pop<uint64_t>(), 5u); 247 } 248 { 249 DataStack data; 250 data.Push(std::string{"A"}); 251 data.Push(std::string{"B"}); 252 data.Push(std::string{"{1}{0}"}); 253 ASSERT_TRUE(Interpret({op_lit_selector, sel_fmt, op_call}, data)); 254 ASSERT_EQ(data.Pop<std::string>(), "BA"); 255 } 256 { 257 DataStack data; 258 data.Push(std::string{"{0}"}); 259 ASSERT_FALSE(Interpret({op_lit_selector, sel_fmt, op_call}, data)); 260 } 261 } 262