/** * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "bytecode_instruction-inl.h" namespace panda::test { TEST(BytecodeInstructionV4_IMM4, Parse) { // V4_IMM4 { const uint8_t bytecode[] = {0x00, 0xa1, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 1); EXPECT_EQ((inst.GetImm()), -6); } { const uint8_t bytecode[] = {0x00, 0x2f, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xf); EXPECT_EQ((inst.GetImm()), 0x2); } } TEST(BytecodeInstructionIMM8, Parse) { // IMM8 { const uint8_t bytecode[] = {0x00, 0xf2, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), static_cast(0xf2)); } { const uint8_t bytecode[] = {0x00, 0x21, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), 0x21); } // V8_IMM8 { const uint8_t bytecode[] = {0x00, 0x12, 0xf2, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x12); EXPECT_EQ((inst.GetImm()), static_cast(0xf2)); } { const uint8_t bytecode[] = {0x00, 0xf2, 0x12, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xf2); EXPECT_EQ((inst.GetImm()), 0x12); } } TEST(BytecodeInstructionIMM16, Parse) { // IMM16 { const uint8_t bytecode[] = {0x00, 0xf2, 0x12, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), 0x12f2); } { const uint8_t bytecode[] = {0x00, 0x12, 0xf2, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), static_cast(0xf212)); } // V8_IMM16 { const uint8_t bytecode[] = {0x00, 0x10, 0xf2, 0x12, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x10); EXPECT_EQ((inst.GetImm()), 0x12f2); } { const uint8_t bytecode[] = {0x00, 0xff, 0x12, 0xf2, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xff); EXPECT_EQ((inst.GetImm()), static_cast(0xf212)); } } TEST(BytecodeInstructionIMM32, Parse) { // IMM32 { const uint8_t bytecode[] = {0x00, 0x34, 0xf2, 0x12, 0x10, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), 0x1012f234); } { const uint8_t bytecode[] = {0x00, 0x34, 0x12, 0xf2, 0xf1, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), static_cast(0xf1f21234)); } // V8_IMM32 { const uint8_t bytecode[] = {0x00, 0x04, 0x34, 0xf2, 0x12, 0x10, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x04); EXPECT_EQ((inst.GetImm()), 0x1012f234); } { const uint8_t bytecode[] = {0x00, 0xaa, 0x34, 0x12, 0xf2, 0xf1, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xaa); EXPECT_EQ((inst.GetImm()), static_cast(0xf1f21234)); } } TEST(BytecodeInstructionIMM64, Parse) { // IMM64 { const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0x4, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), 0x041012f23456789a); } { const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xab, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), static_cast(0xab1012f23456789a)); } // V8_IMM64 { const uint8_t bytecode[] = {0x00, 0x11, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0x4, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x11); EXPECT_EQ((inst.GetImm()), 0x041012f23456789a); } { const uint8_t bytecode[] = {0x00, 0xab, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xab, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xab); EXPECT_EQ((inst.GetImm()), static_cast(0xab1012f23456789a)); } } TEST(BytecodeInstructionV4_V4, Parse) { // V4_V4 { const uint8_t bytecode[] = {0x00, 0xba, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xa); EXPECT_EQ((inst.GetVReg()), 0xb); } } TEST(BytecodeInstructionV8, Parse) { // V8 { const uint8_t bytecode[] = {0x00, 0xab, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xab); } // V8_V8 { const uint8_t bytecode[] = {0x00, 0xab, 0xcd, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xab); EXPECT_EQ((inst.GetVReg()), 0xcd); } } TEST(BytecodeInstructionV16, Parse) { // V16_V16 { const uint8_t bytecode[] = {0x00, 0xcd, 0xab, 0xf1, 0xee, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xabcd); EXPECT_EQ((inst.GetVReg()), 0xeef1); } } TEST(BytecodeInstructionID32, Parse) { // ID32 { const uint8_t bytecode[] = {0x00, 0xf1, 0xee, 0xcd, 0xab, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetId()), BytecodeId(0xabcdeef1)); } } TEST(BytecodeInstructionID16, Parse) { // V4_V4_ID16 { const uint8_t bytecode[] = {0x00, 0x21, 0xf1, 0xee, 0xcd, 0xab, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x1); EXPECT_EQ((inst.GetVReg()), 0x2); EXPECT_EQ((inst.GetId()), BytecodeId(0xeef1)); } // V8_ID16 { const uint8_t bytecode[] = {0x00, 0x12, 0xf1, 0xee, 0xcd, 0xab, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x12); EXPECT_EQ((inst.GetId()), BytecodeId(0xeef1)); } // V4_V4_V4_V4_ID16 { const uint8_t bytecode[] = {0x00, 0x21, 0x43, 0xf1, 0xee, 0xcd, 0xab, 0xff}; BytecodeInstruction inst(bytecode); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x1); EXPECT_EQ((inst.GetVReg()), 0x2); EXPECT_EQ((inst.GetVReg()), 0x3); EXPECT_EQ((inst.GetVReg()), 0x4); EXPECT_EQ((inst.GetId()), BytecodeId(0xeef1)); } } TEST(BytecodeInstruction, JumpTo) { const uint8_t bytecode[] = {0x00, 0x11, 0x22, 0x33}; BytecodeInstruction inst(bytecode); BytecodeInstruction next = inst.JumpTo(2); EXPECT_EQ(static_cast(next.GetOpcode()), bytecode[2]); } // Positive tests TEST(BytecodeInstructionSafeIMM4_P, Parse) { // V4_IMM4 { const uint8_t bytecode[] = {0x00, 0xa1, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 1); EXPECT_EQ((inst.GetImm()), -6); } { const uint8_t bytecode[] = {0x00, 0x2f, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xf); EXPECT_EQ((inst.GetImm()), 0x2); } } TEST(BytecodeInstructionSafeIMM8_P, Parse) { // IMM8 { const uint8_t bytecode[] = {0x00, 0xf2, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), static_cast(0xf2)); } { const uint8_t bytecode[] = {0x00, 0x21, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), 0x21); } // V8_IMM8 { const uint8_t bytecode[] = {0x00, 0x12, 0xf2, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x12); EXPECT_EQ((inst.GetImm()), static_cast(0xf2)); } { const uint8_t bytecode[] = {0x00, 0xf2, 0x12, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xf2); EXPECT_EQ((inst.GetImm()), 0x12); } } TEST(BytecodeInstructionSafeIMM16_P, Parse) { // IMM16 { const uint8_t bytecode[] = {0x00, 0xf2, 0x12, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), 0x12f2); } { const uint8_t bytecode[] = {0x00, 0x12, 0xf2, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), static_cast(0xf212)); } // V8_IMM16 { const uint8_t bytecode[] = {0x00, 0x10, 0xf2, 0x12, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x10); EXPECT_EQ((inst.GetImm()), 0x12f2); } { const uint8_t bytecode[] = {0x00, 0xff, 0x12, 0xf2, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xff); EXPECT_EQ((inst.GetImm()), static_cast(0xf212)); } } TEST(BytecodeInstructionSafeIMM32_P, Parse) { // IMM32 { const uint8_t bytecode[] = {0x00, 0x34, 0xf2, 0x12, 0x10, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), 0x1012f234); } { const uint8_t bytecode[] = {0x00, 0x34, 0x12, 0xf2, 0xf1, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), static_cast(0xf1f21234)); } // V8_IMM32 { const uint8_t bytecode[] = {0x00, 0x04, 0x34, 0xf2, 0x12, 0x10, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x04); EXPECT_EQ((inst.GetImm()), 0x1012f234); } { const uint8_t bytecode[] = {0x00, 0xaa, 0x34, 0x12, 0xf2, 0xf1, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xaa); EXPECT_EQ((inst.GetImm()), static_cast(0xf1f21234)); } } TEST(BytecodeInstructionSafeIMM64_P, Parse) { // IMM64 { const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0x4, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), 0x041012f23456789a); } { const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xab, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetImm()), static_cast(0xab1012f23456789a)); } // V8_IMM64 { const uint8_t bytecode[] = {0x00, 0x11, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0x4, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x11); EXPECT_EQ((inst.GetImm()), 0x041012f23456789a); } { const uint8_t bytecode[] = {0x00, 0xab, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xab, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xab); EXPECT_EQ((inst.GetImm()), static_cast(0xab1012f23456789a)); } } TEST(BytecodeInstructionSafeV4_P, Parse) { // V4_V4 { const uint8_t bytecode[] = {0x00, 0xba, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xa); EXPECT_EQ((inst.GetVReg()), 0xb); } } TEST(BytecodeInstructionSafeV8_P, Parse) { // V8 { const uint8_t bytecode[] = {0x00, 0xab, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xab); } // V8_V8 { const uint8_t bytecode[] = {0x00, 0xab, 0xcd, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xab); EXPECT_EQ((inst.GetVReg()), 0xcd); } } TEST(BytecodeInstructionSafeV16_P, Parse) { // V16_V16 { const uint8_t bytecode[] = {0x00, 0xcd, 0xab, 0xf1, 0xee, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0xabcd); EXPECT_EQ((inst.GetVReg()), 0xeef1); } } TEST(BytecodeInstructionSafeID16_P, Parse) { // ID32 { const uint8_t bytecode[] = {0x00, 0xf1, 0xee, 0xcd, 0xab, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetId()), BytecodeId(0xabcdeef1)); } // V4_V4_ID16 { const uint8_t bytecode[] = {0x00, 0x21, 0xf1, 0xee, 0xcd, 0xab, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x1); EXPECT_EQ((inst.GetVReg()), 0x2); EXPECT_EQ((inst.GetId()), BytecodeId(0xeef1)); } // V8_ID16 { const uint8_t bytecode[] = {0x00, 0x12, 0xf1, 0xee, 0xcd, 0xab, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x12); EXPECT_EQ((inst.GetId()), BytecodeId(0xeef1)); } // V4_V4_V4_V4_ID16 { const uint8_t bytecode[] = {0x00, 0x21, 0x43, 0xf1, 0xee, 0xcd, 0xab, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_EQ((inst.GetVReg()), 0x1); EXPECT_EQ((inst.GetVReg()), 0x2); EXPECT_EQ((inst.GetVReg()), 0x3); EXPECT_EQ((inst.GetVReg()), 0x4); EXPECT_EQ((inst.GetId()), BytecodeId(0xeef1)); } } // Negative tests TEST(BytecodeInstructionSafeIMM4_N, Parse) { // V4_IMM4 { const uint8_t bytecode[] = {0x00}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0); EXPECT_FALSE(inst.IsValid()); } { const uint8_t bytecode[] = {0x00}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetImm()), 0); EXPECT_FALSE(inst.IsValid()); } } TEST(BytecodeInstructionSafeIMM8_N, Parse) { // IMM8 { const uint8_t bytecode[] = {0x00}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetImm()), static_cast(0)); EXPECT_FALSE(inst.IsValid()); } { const uint8_t bytecode[] = {0x00}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetImm()), 0); EXPECT_FALSE(inst.IsValid()); } // V8_IMM8 { const uint8_t bytecode[] = {0x00, 0x12}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0x12); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetImm()), static_cast(0)); EXPECT_FALSE(inst.IsValid()); } } TEST(BytecodeInstructionSafeIMM16_N, Parse) { // IMM16 { const uint8_t bytecode[] = {0x00, 0xf2, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetImm()), 0xf2); EXPECT_FALSE(inst.IsValid()); } // V8_IMM16 { const uint8_t bytecode[] = {0x00, 0x10, 0xf2, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0x10); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetImm()), 0xf2); EXPECT_FALSE(inst.IsValid()); } } TEST(BytecodeInstructionSafeIMM32_N, Parse) { // IMM32 { const uint8_t bytecode[] = {0x00, 0x34, 0xf2, 0x12, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetImm()), 0x12f234); EXPECT_FALSE(inst.IsValid()); } // V8_IMM32 { const uint8_t bytecode[] = {0x00, 0x04, 0x34, 0xf2, 0x12, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0x04); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetImm()), 0x12f234); EXPECT_FALSE(inst.IsValid()); } } TEST(BytecodeInstructionSafeIMM64_N, Parse) { // IMM64 { const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 3]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetImm()), 0x12f23456789a); EXPECT_FALSE(inst.IsValid()); } // V8_IMM64 { const uint8_t bytecode[] = {0x00, 0x11, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 3]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0x11); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetImm()), 0x12f23456789a); EXPECT_FALSE(inst.IsValid()); } } TEST(BytecodeInstructionSafeV4_N, Parse) { // V4_V4 { const uint8_t bytecode[] = {0x00}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0); EXPECT_FALSE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0); EXPECT_FALSE(inst.IsValid()); } } TEST(BytecodeInstructionSafeV8_N, Parse) { // V8 { const uint8_t bytecode[] = {0x00}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0); EXPECT_FALSE(inst.IsValid()); } // V8_V8 { const uint8_t bytecode[] = {0x00, 0xab}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0xab); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0); EXPECT_FALSE(inst.IsValid()); } } TEST(BytecodeInstructionSafeV16_N, Parse) { // V16_V16 { const uint8_t bytecode[] = {0x00, 0xcd, 0xab, 0xf1, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0xabcd); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0xf1); EXPECT_FALSE(inst.IsValid()); } } TEST(BytecodeInstructionSafeID32_N, Parse) { // ID32 { const uint8_t bytecode[] = {0x00, 0xf1, 0xee, 0xcd, 0xff}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetId()), BytecodeId(0xcdeef1)); EXPECT_FALSE(inst.IsValid()); } } TEST(BytecodeInstructionSafeID16_N, Parse) { // V4_V4_ID16 { const uint8_t bytecode[] = {0x00, 0x21, 0xf1, 0xee}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0x1); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0x2); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetId()), BytecodeId(0xf1)); EXPECT_FALSE(inst.IsValid()); } // V8_ID16 { const uint8_t bytecode[] = {0x00, 0x12, 0xf1, 0xee}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 3]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0x12); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetId()), BytecodeId(0x00)); EXPECT_FALSE(inst.IsValid()); } // V4_V4_V4_V4_ID16 { const uint8_t bytecode[] = {0x00, 0x21, 0x43, 0xf1, 0xee}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 3]); EXPECT_EQ(static_cast(inst.GetOpcode()), 0x00); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0x1); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0x2); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0x3); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetVReg()), 0x4); EXPECT_TRUE(inst.IsValid()); EXPECT_EQ((inst.GetId()), BytecodeId(0x0)); EXPECT_FALSE(inst.IsValid()); } } TEST(BytecodeInstructionSafe, JumpTo) { // Positive { const uint8_t bytecode[] = {0x00, 0x11, 0x22, 0x33}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); BytecodeInstructionSafe next = inst.JumpTo(2); EXPECT_EQ(static_cast(next.GetOpcode()), bytecode[2]); } // Negative { const uint8_t bytecode[] = {0x00, 0x11, 0x22, 0x33}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); BytecodeInstructionSafe next = inst.JumpTo(4); EXPECT_FALSE(inst.IsValid()); EXPECT_FALSE(next.IsValid()); } { const uint8_t bytecode[] = {0x00, 0x11, 0x22, 0x33}; BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]); BytecodeInstructionSafe next = inst.JumpTo(-1); EXPECT_FALSE(inst.IsValid()); EXPECT_FALSE(next.IsValid()); } } } // namespace panda::test