• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 
18 #include <type_traits>
19 
20 #include <cstddef>
21 #include <cstdint>
22 
23 #include "bytecode_instruction-inl.h"
24 
25 namespace panda::test {
26 
TEST(BytecodeInstruction,Parse)27 TEST(BytecodeInstruction, Parse)
28 {
29     // V4_IMM4
30     {
31         const uint8_t bytecode[] = {0x00, 0xa1, 0xff};
32         BytecodeInstruction inst(bytecode);
33         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
34         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_IMM4, 0>()), 1);
35         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V4_IMM4, 0>()), -6);
36     }
37 
38     {
39         const uint8_t bytecode[] = {0x00, 0x2f, 0xff};
40         BytecodeInstruction inst(bytecode);
41         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
42         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_IMM4, 0>()), 0xf);
43         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V4_IMM4, 0>()), 0x2);
44     }
45 
46     // IMM8
47     {
48         const uint8_t bytecode[] = {0x00, 0xf2, 0xff};
49         BytecodeInstruction inst(bytecode);
50         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
51         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM8, 0>()), static_cast<int8_t>(0xf2));
52     }
53 
54     {
55         const uint8_t bytecode[] = {0x00, 0x21, 0xff};
56         BytecodeInstruction inst(bytecode);
57         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
58         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM8, 0>()), 0x21);
59     }
60 
61     // V8_IMM8
62     {
63         const uint8_t bytecode[] = {0x00, 0x12, 0xf2, 0xff};
64         BytecodeInstruction inst(bytecode);
65         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
66         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM8, 0>()), 0x12);
67         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM8, 0>()), static_cast<int8_t>(0xf2));
68     }
69 
70     {
71         const uint8_t bytecode[] = {0x00, 0xf2, 0x12, 0xff};
72         BytecodeInstruction inst(bytecode);
73         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
74         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM8, 0>()), 0xf2);
75         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM8, 0>()), 0x12);
76     }
77 
78     // IMM16
79     {
80         const uint8_t bytecode[] = {0x00, 0xf2, 0x12, 0xff};
81         BytecodeInstruction inst(bytecode);
82         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
83         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM16, 0>()), 0x12f2);
84     }
85 
86     {
87         const uint8_t bytecode[] = {0x00, 0x12, 0xf2, 0xff};
88         BytecodeInstruction inst(bytecode);
89         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
90         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM16, 0>()), static_cast<int16_t>(0xf212));
91     }
92 
93     // V8_IMM16
94     {
95         const uint8_t bytecode[] = {0x00, 0x10, 0xf2, 0x12, 0xff};
96         BytecodeInstruction inst(bytecode);
97         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
98         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM16, 0>()), 0x10);
99         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM16, 0>()), 0x12f2);
100     }
101 
102     {
103         const uint8_t bytecode[] = {0x00, 0xff, 0x12, 0xf2, 0xff};
104         BytecodeInstruction inst(bytecode);
105         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
106         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM16, 0>()), 0xff);
107         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM16, 0>()), static_cast<int16_t>(0xf212));
108     }
109 
110     // IMM32
111     {
112         const uint8_t bytecode[] = {0x00, 0x34, 0xf2, 0x12, 0x10, 0xff};
113         BytecodeInstruction inst(bytecode);
114         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
115         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM32, 0>()), 0x1012f234);
116     }
117 
118     {
119         const uint8_t bytecode[] = {0x00, 0x34, 0x12, 0xf2, 0xf1, 0xff};
120         BytecodeInstruction inst(bytecode);
121         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
122         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM32, 0>()), static_cast<int32_t>(0xf1f21234));
123     }
124 
125     // V8_IMM32
126     {
127         const uint8_t bytecode[] = {0x00, 0x04, 0x34, 0xf2, 0x12, 0x10, 0xff};
128         BytecodeInstruction inst(bytecode);
129         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
130         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM32, 0>()), 0x04);
131         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM32, 0>()), 0x1012f234);
132     }
133 
134     {
135         const uint8_t bytecode[] = {0x00, 0xaa, 0x34, 0x12, 0xf2, 0xf1, 0xff};
136         BytecodeInstruction inst(bytecode);
137         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
138         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM32, 0>()), 0xaa);
139         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM32, 0>()), static_cast<int32_t>(0xf1f21234));
140     }
141 
142     // IMM64
143     {
144         const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0x4, 0xff};
145         BytecodeInstruction inst(bytecode);
146         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
147         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM64, 0>()), 0x041012f23456789a);
148     }
149 
150     {
151         const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xab, 0xff};
152         BytecodeInstruction inst(bytecode);
153         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
154         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM64, 0>()), static_cast<int64_t>(0xab1012f23456789a));
155     }
156 
157     // V8_IMM64
158     {
159         const uint8_t bytecode[] = {0x00, 0x11, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0x4, 0xff};
160         BytecodeInstruction inst(bytecode);
161         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
162         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM64, 0>()), 0x11);
163         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM64, 0>()), 0x041012f23456789a);
164     }
165 
166     {
167         const uint8_t bytecode[] = {0x00, 0xab, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xab, 0xff};
168         BytecodeInstruction inst(bytecode);
169         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
170         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM64, 0>()), 0xab);
171         EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM64, 0>()), static_cast<int64_t>(0xab1012f23456789a));
172     }
173 
174     // V4_V4
175     {
176         const uint8_t bytecode[] = {0x00, 0xba, 0xff};
177         BytecodeInstruction inst(bytecode);
178         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
179         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4, 0>()), 0xa);
180         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4, 1>()), 0xb);
181     }
182 
183     // V8
184     {
185         const uint8_t bytecode[] = {0x00, 0xab, 0xff};
186         BytecodeInstruction inst(bytecode);
187         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
188         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8, 0>()), 0xab);
189     }
190 
191     // V8_V8
192     {
193         const uint8_t bytecode[] = {0x00, 0xab, 0xcd, 0xff};
194         BytecodeInstruction inst(bytecode);
195         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
196         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_V8, 0>()), 0xab);
197         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_V8, 1>()), 0xcd);
198     }
199 
200     // V16_V16
201     {
202         const uint8_t bytecode[] = {0x00, 0xcd, 0xab, 0xf1, 0xee, 0xff};
203         BytecodeInstruction inst(bytecode);
204         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
205         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V16_V16, 0>()), 0xabcd);
206         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V16_V16, 1>()), 0xeef1);
207     }
208 
209     // ID32
210     {
211         const uint8_t bytecode[] = {0x00, 0xf1, 0xee, 0xcd, 0xab, 0xff};
212         BytecodeInstruction inst(bytecode);
213         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
214         EXPECT_EQ((inst.GetId<BytecodeInstruction::Format::ID32, 0>()), BytecodeId(0xabcdeef1));
215     }
216 
217     // V4_V4_ID16
218     {
219         const uint8_t bytecode[] = {0x00, 0x21, 0xf1, 0xee, 0xcd, 0xab, 0xff};
220         BytecodeInstruction inst(bytecode);
221         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
222         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4_ID16, 0>()), 0x1);
223         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4_ID16, 1>()), 0x2);
224         EXPECT_EQ((inst.GetId<BytecodeInstruction::Format::V4_V4_ID16, 0>()), BytecodeId(0xeef1));
225     }
226 
227     // V8_ID16
228     {
229         const uint8_t bytecode[] = {0x00, 0x12, 0xf1, 0xee, 0xcd, 0xab, 0xff};
230         BytecodeInstruction inst(bytecode);
231         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
232         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_ID16, 0>()), 0x12);
233         EXPECT_EQ((inst.GetId<BytecodeInstruction::Format::V8_ID16, 0>()), BytecodeId(0xeef1));
234     }
235 
236     // V4_V4_V4_V4_ID16
237     {
238         const uint8_t bytecode[] = {0x00, 0x21, 0x43, 0xf1, 0xee, 0xcd, 0xab, 0xff};
239         BytecodeInstruction inst(bytecode);
240         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
241         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4_V4_V4_ID16, 0x0>()), 0x1);
242         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4_V4_V4_ID16, 0x1>()), 0x2);
243         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4_V4_V4_ID16, 0x2>()), 0x3);
244         EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4_V4_V4_ID16, 0x3>()), 0x4);
245         EXPECT_EQ((inst.GetId<BytecodeInstruction::Format::V4_V4_V4_V4_ID16, 0>()), BytecodeId(0xeef1));
246     }
247 }
248 
TEST(BytecodeInstruction,JumpTo)249 TEST(BytecodeInstruction, JumpTo)
250 {
251     const uint8_t bytecode[] = {0x00, 0x11, 0x22, 0x33};
252     BytecodeInstruction inst(bytecode);
253     BytecodeInstruction next = inst.JumpTo(2);
254     EXPECT_EQ(static_cast<uint8_t>(next.GetOpcode()), bytecode[2]);
255 }
256 
TEST(BytecodeInstructionSafe,Parse)257 TEST(BytecodeInstructionSafe, Parse)
258 {
259     // Positive tests
260     // V4_IMM4
261     {
262         const uint8_t bytecode[] = {0x00, 0xa1, 0xff};
263         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
264         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
265         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_IMM4, 0>()), 1);
266         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V4_IMM4, 0>()), -6);
267     }
268 
269     {
270         const uint8_t bytecode[] = {0x00, 0x2f, 0xff};
271         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
272         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
273         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_IMM4, 0>()), 0xf);
274         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V4_IMM4, 0>()), 0x2);
275     }
276 
277     // IMM8
278     {
279         const uint8_t bytecode[] = {0x00, 0xf2, 0xff};
280         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
281         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
282         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM8, 0>()), static_cast<int8_t>(0xf2));
283     }
284 
285     {
286         const uint8_t bytecode[] = {0x00, 0x21, 0xff};
287         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
288         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
289         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM8, 0>()), 0x21);
290     }
291 
292     // V8_IMM8
293     {
294         const uint8_t bytecode[] = {0x00, 0x12, 0xf2, 0xff};
295         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
296         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
297         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM8, 0>()), 0x12);
298         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM8, 0>()), static_cast<int8_t>(0xf2));
299     }
300 
301     {
302         const uint8_t bytecode[] = {0x00, 0xf2, 0x12, 0xff};
303         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
304         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
305         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM8, 0>()), 0xf2);
306         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM8, 0>()), 0x12);
307     }
308 
309     // IMM16
310     {
311         const uint8_t bytecode[] = {0x00, 0xf2, 0x12, 0xff};
312         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
313         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
314         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM16, 0>()), 0x12f2);
315     }
316 
317     {
318         const uint8_t bytecode[] = {0x00, 0x12, 0xf2, 0xff};
319         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
320         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
321         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM16, 0>()), static_cast<int16_t>(0xf212));
322     }
323 
324     // V8_IMM16
325     {
326         const uint8_t bytecode[] = {0x00, 0x10, 0xf2, 0x12, 0xff};
327         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
328         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
329         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM16, 0>()), 0x10);
330         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM16, 0>()), 0x12f2);
331     }
332 
333     {
334         const uint8_t bytecode[] = {0x00, 0xff, 0x12, 0xf2, 0xff};
335         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
336         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
337         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM16, 0>()), 0xff);
338         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM16, 0>()), static_cast<int16_t>(0xf212));
339     }
340 
341     // IMM32
342     {
343         const uint8_t bytecode[] = {0x00, 0x34, 0xf2, 0x12, 0x10, 0xff};
344         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
345         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
346         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM32, 0>()), 0x1012f234);
347     }
348 
349     {
350         const uint8_t bytecode[] = {0x00, 0x34, 0x12, 0xf2, 0xf1, 0xff};
351         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
352         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
353         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM32, 0>()), static_cast<int32_t>(0xf1f21234));
354     }
355 
356     // V8_IMM32
357     {
358         const uint8_t bytecode[] = {0x00, 0x04, 0x34, 0xf2, 0x12, 0x10, 0xff};
359         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
360         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
361         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM32, 0>()), 0x04);
362         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM32, 0>()), 0x1012f234);
363     }
364 
365     {
366         const uint8_t bytecode[] = {0x00, 0xaa, 0x34, 0x12, 0xf2, 0xf1, 0xff};
367         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
368         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
369         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM32, 0>()), 0xaa);
370         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM32, 0>()), static_cast<int32_t>(0xf1f21234));
371     }
372 
373     // IMM64
374     {
375         const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0x4, 0xff};
376         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
377         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
378         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM64, 0>()), 0x041012f23456789a);
379     }
380 
381     {
382         const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xab, 0xff};
383         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
384         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
385         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM64, 0>()), static_cast<int64_t>(0xab1012f23456789a));
386     }
387 
388     // V8_IMM64
389     {
390         const uint8_t bytecode[] = {0x00, 0x11, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0x4, 0xff};
391         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
392         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
393         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM64, 0>()), 0x11);
394         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM64, 0>()), 0x041012f23456789a);
395     }
396 
397     {
398         const uint8_t bytecode[] = {0x00, 0xab, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xab, 0xff};
399         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
400         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
401         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM64, 0>()), 0xab);
402         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM64, 0>()),
403                   static_cast<int64_t>(0xab1012f23456789a));
404     }
405 
406     // V4_V4
407     {
408         const uint8_t bytecode[] = {0x00, 0xba, 0xff};
409         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
410         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
411         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4, 0>()), 0xa);
412         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4, 1>()), 0xb);
413     }
414 
415     // V8
416     {
417         const uint8_t bytecode[] = {0x00, 0xab, 0xff};
418         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
419         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
420         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8, 0>()), 0xab);
421     }
422 
423     // V8_V8
424     {
425         const uint8_t bytecode[] = {0x00, 0xab, 0xcd, 0xff};
426         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
427         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
428         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_V8, 0>()), 0xab);
429         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_V8, 1>()), 0xcd);
430     }
431 
432     // V16_V16
433     {
434         const uint8_t bytecode[] = {0x00, 0xcd, 0xab, 0xf1, 0xee, 0xff};
435         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
436         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
437         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V16_V16, 0>()), 0xabcd);
438         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V16_V16, 1>()), 0xeef1);
439     }
440 
441     // ID32
442     {
443         const uint8_t bytecode[] = {0x00, 0xf1, 0xee, 0xcd, 0xab, 0xff};
444         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
445         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
446         EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::ID32, 0>()), BytecodeId(0xabcdeef1));
447     }
448 
449     // V4_V4_ID16
450     {
451         const uint8_t bytecode[] = {0x00, 0x21, 0xf1, 0xee, 0xcd, 0xab, 0xff};
452         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
453         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
454         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_ID16, 0>()), 0x1);
455         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_ID16, 1>()), 0x2);
456         EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::V4_V4_ID16, 0>()), BytecodeId(0xeef1));
457     }
458 
459     // V8_ID16
460     {
461         const uint8_t bytecode[] = {0x00, 0x12, 0xf1, 0xee, 0xcd, 0xab, 0xff};
462         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
463         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
464         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_ID16, 0>()), 0x12);
465         EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::V8_ID16, 0>()), BytecodeId(0xeef1));
466     }
467 
468     // V4_V4_V4_V4_ID16
469     {
470         const uint8_t bytecode[] = {0x00, 0x21, 0x43, 0xf1, 0xee, 0xcd, 0xab, 0xff};
471         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
472         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
473         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x0>()), 0x1);
474         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x1>()), 0x2);
475         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x2>()), 0x3);
476         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x3>()), 0x4);
477         EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0>()), BytecodeId(0xeef1));
478     }
479 
480     // Negative tests
481 
482     // V4_IMM4
483     {
484         const uint8_t bytecode[] = {0x00};
485         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
486         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
487         EXPECT_TRUE(inst.IsValid());
488         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_IMM4, 0>()), 0);
489         EXPECT_FALSE(inst.IsValid());
490     }
491 
492     {
493         const uint8_t bytecode[] = {0x00};
494         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
495         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
496         EXPECT_TRUE(inst.IsValid());
497         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V4_IMM4, 0>()), 0);
498         EXPECT_FALSE(inst.IsValid());
499     }
500 
501     // IMM8
502     {
503         const uint8_t bytecode[] = {0x00};
504         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
505         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
506         EXPECT_TRUE(inst.IsValid());
507         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM8, 0>()), static_cast<int8_t>(0));
508         EXPECT_FALSE(inst.IsValid());
509     }
510 
511     {
512         const uint8_t bytecode[] = {0x00};
513         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
514         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
515         EXPECT_TRUE(inst.IsValid());
516         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM8, 0>()), 0);
517         EXPECT_FALSE(inst.IsValid());
518     }
519 
520     // V8_IMM8
521     {
522         const uint8_t bytecode[] = {0x00, 0x12};
523         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
524         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
525         EXPECT_TRUE(inst.IsValid());
526         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM8, 0>()), 0x12);
527         EXPECT_TRUE(inst.IsValid());
528         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM8, 0>()), static_cast<int8_t>(0));
529         EXPECT_FALSE(inst.IsValid());
530     }
531 
532     // IMM16
533     {
534         const uint8_t bytecode[] = {0x00, 0xf2, 0xff};
535         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
536         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
537         EXPECT_TRUE(inst.IsValid());
538         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM16, 0>()), 0xf2);
539         EXPECT_FALSE(inst.IsValid());
540     }
541 
542     // V8_IMM16
543     {
544         const uint8_t bytecode[] = {0x00, 0x10, 0xf2, 0xff};
545         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
546         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
547         EXPECT_TRUE(inst.IsValid());
548         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM16, 0>()), 0x10);
549         EXPECT_TRUE(inst.IsValid());
550         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM16, 0>()), 0xf2);
551         EXPECT_FALSE(inst.IsValid());
552     }
553 
554     // IMM32
555     {
556         const uint8_t bytecode[] = {0x00, 0x34, 0xf2, 0x12, 0xff};
557         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
558         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
559         EXPECT_TRUE(inst.IsValid());
560         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM32, 0>()), 0x12f234);
561         EXPECT_FALSE(inst.IsValid());
562     }
563 
564     // V8_IMM32
565     {
566         const uint8_t bytecode[] = {0x00, 0x04, 0x34, 0xf2, 0x12, 0xff};
567         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
568         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
569         EXPECT_TRUE(inst.IsValid());
570         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM32, 0>()), 0x04);
571         EXPECT_TRUE(inst.IsValid());
572         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM32, 0>()), 0x12f234);
573         EXPECT_FALSE(inst.IsValid());
574     }
575 
576     // IMM64
577     {
578         const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xff};
579         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 3]);
580         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
581         EXPECT_TRUE(inst.IsValid());
582         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM64, 0>()), 0x12f23456789a);
583         EXPECT_FALSE(inst.IsValid());
584     }
585 
586     // V8_IMM64
587     {
588         const uint8_t bytecode[] = {0x00, 0x11, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xff};
589         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 3]);
590         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
591         EXPECT_TRUE(inst.IsValid());
592         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM64, 0>()), 0x11);
593         EXPECT_TRUE(inst.IsValid());
594         EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM64, 0>()), 0x12f23456789a);
595         EXPECT_FALSE(inst.IsValid());
596     }
597 
598     // V4_V4
599     {
600         const uint8_t bytecode[] = {0x00};
601         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
602         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
603         EXPECT_TRUE(inst.IsValid());
604         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4, 0>()), 0);
605         EXPECT_FALSE(inst.IsValid());
606         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4, 1>()), 0);
607         EXPECT_FALSE(inst.IsValid());
608     }
609 
610     // V8
611     {
612         const uint8_t bytecode[] = {0x00};
613         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
614         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
615         EXPECT_TRUE(inst.IsValid());
616         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8, 0>()), 0);
617         EXPECT_FALSE(inst.IsValid());
618     }
619 
620     // V8_V8
621     {
622         const uint8_t bytecode[] = {0x00, 0xab};
623         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
624         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
625         EXPECT_TRUE(inst.IsValid());
626         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_V8, 0>()), 0xab);
627         EXPECT_TRUE(inst.IsValid());
628         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_V8, 1>()), 0);
629         EXPECT_FALSE(inst.IsValid());
630     }
631 
632     // V16_V16
633     {
634         const uint8_t bytecode[] = {0x00, 0xcd, 0xab, 0xf1, 0xff};
635         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
636         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
637         EXPECT_TRUE(inst.IsValid());
638         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V16_V16, 0>()), 0xabcd);
639         EXPECT_TRUE(inst.IsValid());
640         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V16_V16, 1>()), 0xf1);
641         EXPECT_FALSE(inst.IsValid());
642     }
643 
644     // ID32
645     {
646         const uint8_t bytecode[] = {0x00, 0xf1, 0xee, 0xcd, 0xff};
647         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
648         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
649         EXPECT_TRUE(inst.IsValid());
650         EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::ID32, 0>()), BytecodeId(0xcdeef1));
651         EXPECT_FALSE(inst.IsValid());
652     }
653 
654     // V4_V4_ID16
655     {
656         const uint8_t bytecode[] = {0x00, 0x21, 0xf1, 0xee};
657         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
658         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
659         EXPECT_TRUE(inst.IsValid());
660         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_ID16, 0>()), 0x1);
661         EXPECT_TRUE(inst.IsValid());
662         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_ID16, 1>()), 0x2);
663         EXPECT_TRUE(inst.IsValid());
664         EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::V4_V4_ID16, 0>()), BytecodeId(0xf1));
665         EXPECT_FALSE(inst.IsValid());
666     }
667 
668     // V8_ID16
669     {
670         const uint8_t bytecode[] = {0x00, 0x12, 0xf1, 0xee};
671         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 3]);
672         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
673         EXPECT_TRUE(inst.IsValid());
674         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_ID16, 0>()), 0x12);
675         EXPECT_TRUE(inst.IsValid());
676         EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::V8_ID16, 0>()), BytecodeId(0x00));
677         EXPECT_FALSE(inst.IsValid());
678     }
679 
680     // V4_V4_V4_V4_ID16
681     {
682         const uint8_t bytecode[] = {0x00, 0x21, 0x43, 0xf1, 0xee};
683         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 3]);
684         EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
685         EXPECT_TRUE(inst.IsValid());
686         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x0>()), 0x1);
687         EXPECT_TRUE(inst.IsValid());
688         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x1>()), 0x2);
689         EXPECT_TRUE(inst.IsValid());
690         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x2>()), 0x3);
691         EXPECT_TRUE(inst.IsValid());
692         EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x3>()), 0x4);
693         EXPECT_TRUE(inst.IsValid());
694         EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0>()), BytecodeId(0x0));
695         EXPECT_FALSE(inst.IsValid());
696     }
697 }
698 
TEST(BytecodeInstructionSafe,JumpTo)699 TEST(BytecodeInstructionSafe, JumpTo)
700 {
701     // Positive
702     {
703         const uint8_t bytecode[] = {0x00, 0x11, 0x22, 0x33};
704         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
705         BytecodeInstructionSafe next = inst.JumpTo(2);
706         EXPECT_EQ(static_cast<uint8_t>(next.GetOpcode()), bytecode[2]);
707     }
708     // Negative
709     {
710         const uint8_t bytecode[] = {0x00, 0x11, 0x22, 0x33};
711         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
712         BytecodeInstructionSafe next = inst.JumpTo(4);
713         EXPECT_FALSE(inst.IsValid());
714         EXPECT_FALSE(next.IsValid());
715     }
716     {
717         const uint8_t bytecode[] = {0x00, 0x11, 0x22, 0x33};
718         BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
719         BytecodeInstructionSafe next = inst.JumpTo(-1);
720         EXPECT_FALSE(inst.IsValid());
721         EXPECT_FALSE(next.IsValid());
722     }
723 }
724 
725 }  // namespace panda::test
726