187659a17SAdrian Prantl #include "DataFormatters/FormatterBytecode.h" 287659a17SAdrian Prantl #include "lldb/Utility/StreamString.h" 387659a17SAdrian Prantl 487659a17SAdrian Prantl #include "gtest/gtest.h" 587659a17SAdrian Prantl 687659a17SAdrian Prantl using namespace lldb_private; 787659a17SAdrian Prantl using namespace lldb; 887659a17SAdrian Prantl using namespace FormatterBytecode; 987659a17SAdrian Prantl using llvm::StringRef; 1087659a17SAdrian Prantl 1187659a17SAdrian Prantl namespace { 1287659a17SAdrian Prantl class FormatterBytecodeTest : public ::testing::Test {}; 1387659a17SAdrian Prantl 1487659a17SAdrian Prantl bool Interpret(std::vector<uint8_t> code, DataStack &data) { 1587659a17SAdrian Prantl auto buf = 1687659a17SAdrian Prantl StringRef(reinterpret_cast<const char *>(code.data()), code.size()); 1787659a17SAdrian Prantl std::vector<ControlStackElement> control({buf}); 1887659a17SAdrian Prantl if (auto error = Interpret(control, data, sel_summary)) { 1987659a17SAdrian Prantl #ifndef NDEBUG 2087659a17SAdrian Prantl llvm::errs() << llvm::toString(std::move(error)) << '\n'; 2187659a17SAdrian Prantl #else 2287659a17SAdrian Prantl llvm::consumeError(std::move(error)); 2387659a17SAdrian Prantl #endif 2487659a17SAdrian Prantl return false; 2587659a17SAdrian Prantl } 2687659a17SAdrian Prantl return true; 2787659a17SAdrian Prantl } 2887659a17SAdrian Prantl 2987659a17SAdrian Prantl } // namespace 3087659a17SAdrian Prantl 3187659a17SAdrian Prantl TEST_F(FormatterBytecodeTest, StackOps) { 3287659a17SAdrian Prantl { 3387659a17SAdrian Prantl DataStack data; 3487659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 23, op_dup, op_plus}, data)); 3587659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 46u); 3687659a17SAdrian Prantl } 3787659a17SAdrian Prantl { 3887659a17SAdrian Prantl DataStack data; 3987659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_drop}, data)); 4087659a17SAdrian Prantl ASSERT_EQ(data.size(), 0u); 4187659a17SAdrian Prantl } 4287659a17SAdrian Prantl { 4387659a17SAdrian Prantl for (unsigned char i = 0; i < 3; ++i) { 4487659a17SAdrian Prantl DataStack data; 4587659a17SAdrian Prantl 4687659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_lit_uint, 2, 4787659a17SAdrian Prantl op_lit_uint, i, op_pick}, 4887659a17SAdrian Prantl data)); 4987659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), i); 5087659a17SAdrian Prantl } 5187659a17SAdrian Prantl } 5287659a17SAdrian Prantl { 5387659a17SAdrian Prantl DataStack data; 5487659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_over}, data)); 5587659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 5687659a17SAdrian Prantl } 5787659a17SAdrian Prantl { 5887659a17SAdrian Prantl DataStack data; 5987659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_swap}, data)); 6087659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 6187659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 6287659a17SAdrian Prantl } 6387659a17SAdrian Prantl { 6487659a17SAdrian Prantl DataStack data; 6587659a17SAdrian Prantl ASSERT_TRUE(Interpret( 6687659a17SAdrian Prantl {op_lit_uint, 0, op_lit_uint, 1, op_lit_uint, 2, op_rot}, data)); 6787659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 6887659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 6987659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 2u); 7087659a17SAdrian Prantl } 7187659a17SAdrian Prantl } 7287659a17SAdrian Prantl 7387659a17SAdrian Prantl TEST_F(FormatterBytecodeTest, ControlOps) { 7487659a17SAdrian Prantl { 7587659a17SAdrian Prantl DataStack data; 7687659a17SAdrian Prantl ASSERT_TRUE( 7787659a17SAdrian Prantl Interpret({op_lit_uint, 0, op_begin, 2, op_lit_uint, 42, op_if}, data)); 7887659a17SAdrian Prantl ASSERT_EQ(data.size(), 0u); 7987659a17SAdrian Prantl } 8087659a17SAdrian Prantl { 8187659a17SAdrian Prantl DataStack data; 8287659a17SAdrian Prantl ASSERT_TRUE( 8387659a17SAdrian Prantl Interpret({op_lit_uint, 1, op_begin, 2, op_lit_uint, 42, op_if}, data)); 8487659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 42u); 8587659a17SAdrian Prantl } 8687659a17SAdrian Prantl { 8787659a17SAdrian Prantl DataStack data; 8887659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_begin, 2, op_lit_uint, 42, 8987659a17SAdrian Prantl op_begin, 2, op_lit_uint, 23, op_ifelse}, 9087659a17SAdrian Prantl data)); 9187659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 23u); 9287659a17SAdrian Prantl } 9387659a17SAdrian Prantl { 9487659a17SAdrian Prantl DataStack data; 9587659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_begin, 2, op_lit_uint, 42, 9687659a17SAdrian Prantl op_begin, 2, op_lit_uint, 23, op_ifelse}, 9787659a17SAdrian Prantl data)); 9887659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 42u); 9987659a17SAdrian Prantl } 10087659a17SAdrian Prantl { 101*ee1adc5aSAdrian Prantl DataStack data; 102*ee1adc5aSAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_begin, 3, op_lit_uint, 42, 103*ee1adc5aSAdrian Prantl op_return, op_if, op_lit_uint, 23}, 104*ee1adc5aSAdrian Prantl data)); 105*ee1adc5aSAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 42u); 106*ee1adc5aSAdrian Prantl } 107*ee1adc5aSAdrian Prantl } 108*ee1adc5aSAdrian Prantl 109*ee1adc5aSAdrian Prantl TEST_F(FormatterBytecodeTest, ConversionOps) { 110*ee1adc5aSAdrian Prantl { 11187659a17SAdrian Prantl DataStack data(lldb::ValueObjectSP{}); 11287659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_is_null}, data)); 11387659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 11487659a17SAdrian Prantl } 11587659a17SAdrian Prantl { 11687659a17SAdrian Prantl DataStack data; 11787659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1u, op_as_int}, data)); 11887659a17SAdrian Prantl ASSERT_EQ(data.Pop<int64_t>(), 1); 11987659a17SAdrian Prantl } 12087659a17SAdrian Prantl { 12187659a17SAdrian Prantl DataStack data; 12287659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_int, 126, op_as_uint}, data)); 12387659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), ~1ULL); 12487659a17SAdrian Prantl } 12587659a17SAdrian Prantl } 12687659a17SAdrian Prantl 12787659a17SAdrian Prantl TEST_F(FormatterBytecodeTest, ArithOps) { 12887659a17SAdrian Prantl { 12987659a17SAdrian Prantl DataStack data; 13087659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 2, op_lit_uint, 3, op_plus}, data)); 13187659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 5u); 13287659a17SAdrian Prantl } 13387659a17SAdrian Prantl { 13487659a17SAdrian Prantl DataStack data; 13587659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 3, op_lit_uint, 2, op_minus}, data)); 13687659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 13787659a17SAdrian Prantl } 13887659a17SAdrian Prantl { 13987659a17SAdrian Prantl DataStack data; 14087659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 3, op_lit_uint, 2, op_mul}, data)); 14187659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 6u); 14287659a17SAdrian Prantl } 14387659a17SAdrian Prantl { 14487659a17SAdrian Prantl DataStack data; 14587659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 6, op_lit_uint, 2, op_div}, data)); 14687659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 3u); 14787659a17SAdrian Prantl } 14887659a17SAdrian Prantl { 14987659a17SAdrian Prantl DataStack data; 15087659a17SAdrian Prantl ASSERT_FALSE(Interpret({op_lit_uint, 23, op_lit_uint, 0, op_div}, data)); 15187659a17SAdrian Prantl } 15287659a17SAdrian Prantl { 15387659a17SAdrian Prantl DataStack data; 15487659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 2, op_shl}, data)); 15587659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 4u); 15687659a17SAdrian Prantl } 15787659a17SAdrian Prantl { 15887659a17SAdrian Prantl DataStack data; 15987659a17SAdrian Prantl unsigned char minus_one = 127; 1602470cfabSAdrian Prantl ASSERT_FALSE( 16187659a17SAdrian Prantl Interpret({op_lit_int, minus_one, op_lit_uint, 2, op_shl}, data)); 1622470cfabSAdrian Prantl unsigned char minus_two = 126; 1632470cfabSAdrian Prantl ASSERT_TRUE( 1642470cfabSAdrian Prantl Interpret({op_lit_int, minus_two, op_lit_uint, 1, op_shr}, data)); 1652470cfabSAdrian Prantl ASSERT_EQ(data.Pop<int64_t>(), -1); 16687659a17SAdrian Prantl } 16787659a17SAdrian Prantl { 16887659a17SAdrian Prantl DataStack data; 16987659a17SAdrian Prantl ASSERT_FALSE(Interpret({op_lit_uint, 1, op_lit_uint, 65, op_shl}, data)); 17087659a17SAdrian Prantl ASSERT_FALSE(Interpret({op_lit_uint, 1, op_lit_uint, 65, op_shr}, data)); 17187659a17SAdrian Prantl } 17287659a17SAdrian Prantl { 17387659a17SAdrian Prantl DataStack data; 17487659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_and}, data)); 17587659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 17687659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_and}, data)); 17787659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 17887659a17SAdrian Prantl } 17987659a17SAdrian Prantl { 18087659a17SAdrian Prantl DataStack data; 18187659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_or}, data)); 18287659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 18387659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_or}, data)); 18487659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 18587659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_or}, data)); 18687659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 18787659a17SAdrian Prantl } 18887659a17SAdrian Prantl { 18987659a17SAdrian Prantl DataStack data; 19087659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_xor}, data)); 19187659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 19287659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_xor}, data)); 19387659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 19487659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_xor}, data)); 19587659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 19687659a17SAdrian Prantl } 19787659a17SAdrian Prantl { 19887659a17SAdrian Prantl DataStack data; 19987659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_not}, data)); 20087659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0xffffffffffffffff); 20187659a17SAdrian Prantl } 20287659a17SAdrian Prantl { 20387659a17SAdrian Prantl DataStack data; 20487659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_eq}, data)); 20587659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 20687659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_eq}, data)); 20787659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 20887659a17SAdrian Prantl } 20987659a17SAdrian Prantl { 21087659a17SAdrian Prantl DataStack data; 21187659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_neq}, data)); 21287659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 21387659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 0, op_neq}, data)); 21487659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 21587659a17SAdrian Prantl } 21687659a17SAdrian Prantl { 21787659a17SAdrian Prantl DataStack data; 21887659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_lt}, data)); 21987659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 22087659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_lt}, data)); 22187659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 22287659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_lt}, data)); 22387659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 22487659a17SAdrian Prantl } 22587659a17SAdrian Prantl { 22687659a17SAdrian Prantl DataStack data; 22787659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_gt}, data)); 22887659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 22987659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_gt}, data)); 23087659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 23187659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_gt}, data)); 23287659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 23387659a17SAdrian Prantl } 23487659a17SAdrian Prantl { 23587659a17SAdrian Prantl DataStack data; 23687659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_le}, data)); 23787659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 23887659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_le}, data)); 23987659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 24087659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_le}, data)); 24187659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 24287659a17SAdrian Prantl } 24387659a17SAdrian Prantl { 24487659a17SAdrian Prantl DataStack data; 24587659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 0, op_lit_uint, 1, op_ge}, data)); 24687659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 0u); 24787659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 0, op_ge}, data)); 24887659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 24987659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_uint, 1, op_lit_uint, 1, op_ge}, data)); 25087659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 1u); 25187659a17SAdrian Prantl } 25287659a17SAdrian Prantl } 25387659a17SAdrian Prantl 25487659a17SAdrian Prantl TEST_F(FormatterBytecodeTest, CallOps) { 25587659a17SAdrian Prantl { 25687659a17SAdrian Prantl DataStack data; 25787659a17SAdrian Prantl data.Push(std::string{"hello"}); 25887659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_selector, sel_strlen, op_call}, data)); 25987659a17SAdrian Prantl ASSERT_EQ(data.Pop<uint64_t>(), 5u); 26087659a17SAdrian Prantl } 26187659a17SAdrian Prantl { 26287659a17SAdrian Prantl DataStack data; 26387659a17SAdrian Prantl data.Push(std::string{"A"}); 26487659a17SAdrian Prantl data.Push(std::string{"B"}); 26587659a17SAdrian Prantl data.Push(std::string{"{1}{0}"}); 26687659a17SAdrian Prantl ASSERT_TRUE(Interpret({op_lit_selector, sel_fmt, op_call}, data)); 26787659a17SAdrian Prantl ASSERT_EQ(data.Pop<std::string>(), "BA"); 26887659a17SAdrian Prantl } 26987659a17SAdrian Prantl { 27087659a17SAdrian Prantl DataStack data; 27187659a17SAdrian Prantl data.Push(std::string{"{0}"}); 27287659a17SAdrian Prantl ASSERT_FALSE(Interpret({op_lit_selector, sel_fmt, op_call}, data)); 27387659a17SAdrian Prantl } 27487659a17SAdrian Prantl } 275