Line data Source code
1 : // Copyright 2015 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include <vector>
6 :
7 : #include "src/v8.h"
8 :
9 : #include "src/contexts.h"
10 : #include "src/interpreter/bytecode-decoder.h"
11 : #include "src/runtime/runtime.h"
12 : #include "test/unittests/interpreter/bytecode-utils.h"
13 : #include "test/unittests/test-utils.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 : namespace interpreter {
18 :
19 : #define B(Name) static_cast<uint8_t>(Bytecode::k##Name)
20 :
21 15188 : TEST(BytecodeDecoder, DecodeBytecodeAndOperands) {
22 : struct BytecodesAndResult {
23 : const uint8_t bytecode[32];
24 : const size_t length;
25 : int parameter_count;
26 : const char* output;
27 : };
28 :
29 : const BytecodesAndResult cases[] = {
30 : {{B(LdaSmi), U8(1)}, 2, 0, " LdaSmi [1]"},
31 : {{B(Wide), B(LdaSmi), U16(1000)}, 4, 0, " LdaSmi.Wide [1000]"},
32 : {{B(ExtraWide), B(LdaSmi), U32(100000)},
33 : 6,
34 : 0,
35 : "LdaSmi.ExtraWide [100000]"},
36 : {{B(LdaSmi), U8(-1)}, 2, 0, " LdaSmi [-1]"},
37 : {{B(Wide), B(LdaSmi), U16(-1000)}, 4, 0, " LdaSmi.Wide [-1000]"},
38 : {{B(ExtraWide), B(LdaSmi), U32(-100000)},
39 : 6,
40 : 0,
41 : "LdaSmi.ExtraWide [-100000]"},
42 : {{B(Star), R8(5)}, 2, 0, " Star r5"},
43 : {{B(Wide), B(Star), R16(136)}, 4, 0, " Star.Wide r136"},
44 : {{B(Wide), B(CallAnyReceiver), R16(134), R16(135), U16(10), U16(177)},
45 : 10,
46 : 0,
47 : "CallAnyReceiver.Wide r134, r135-r144, [177]"},
48 : {{B(ForInPrepare), R8(10), U8(11)},
49 : 3,
50 : 0,
51 : " ForInPrepare r10-r12, [11]"},
52 : {{B(CallRuntime), U16(Runtime::FunctionId::kIsSmi), R8(0), U8(0)},
53 : 5,
54 : 0,
55 : " CallRuntime [IsSmi], r0-r0"},
56 : {{B(Ldar),
57 2 : static_cast<uint8_t>(Register::FromParameterIndex(2, 3).ToOperand())},
58 : 2,
59 : 3,
60 : " Ldar a1"},
61 : {{B(Wide), B(CreateObjectLiteral), U16(513), U16(1027), U8(165)},
62 : 7,
63 : 0,
64 : "CreateObjectLiteral.Wide [513], [1027], #165"},
65 : {{B(ExtraWide), B(JumpIfNull), U32(123456789)},
66 : 6,
67 : 0,
68 : "JumpIfNull.ExtraWide [123456789]"},
69 : {{B(CallJSRuntime), U8(Context::BOOLEAN_FUNCTION_INDEX), R8(0), U8(0)},
70 : 4,
71 : 0,
72 2 : " CallJSRuntime [boolean_function], r0-r0"}};
73 :
74 16 : for (size_t i = 0; i < arraysize(cases); ++i) {
75 : // Generate reference string by prepending formatted bytes.
76 15 : std::stringstream expected_ss;
77 15 : std::ios default_format(nullptr);
78 15 : default_format.copyfmt(expected_ss);
79 : // Match format of BytecodeDecoder::Decode() for byte representations.
80 : expected_ss.fill('0');
81 : expected_ss.flags(std::ios::right | std::ios::hex);
82 82 : for (size_t b = 0; b < cases[i].length; b++) {
83 67 : expected_ss << std::setw(2) << static_cast<uint32_t>(cases[i].bytecode[b])
84 : << ' ';
85 : }
86 15 : expected_ss.copyfmt(default_format);
87 15 : expected_ss << cases[i].output;
88 :
89 : // Generate decoded byte output.
90 30 : std::stringstream actual_ss;
91 : BytecodeDecoder::Decode(actual_ss, cases[i].bytecode,
92 15 : cases[i].parameter_count);
93 :
94 : // Compare.
95 30 : CHECK_EQ(actual_ss.str(), expected_ss.str());
96 15 : }
97 1 : }
98 :
99 : #undef B
100 :
101 : } // namespace interpreter
102 : } // namespace internal
103 9111 : } // namespace v8
|