/src/hermes/lib/VM/InstLayout.inc
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) Meta Platforms, Inc. and affiliates. |
3 | | * |
4 | | * This source code is licensed under the MIT license found in the |
5 | | * LICENSE file in the root directory of this source tree. |
6 | | */ |
7 | | |
8 | | //===----------------------------------------------------------------------===// |
9 | | /// \file |
10 | | /// Check at compile time that instructions declared as having the same layout |
11 | | /// actually do. |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | namespace hermes { |
15 | | namespace vm { |
16 | | |
17 | | /// \return true if the sequence v1, v2, v3... is monotone increasing, that is, |
18 | | /// satisfies v1 <= v2 <= v3... |
19 | 0 | static constexpr bool monotoneIncreasing(size_t v1, size_t v2) { |
20 | 0 | return v1 <= v2; |
21 | 0 | } |
22 | | |
23 | | template <typename... Args> |
24 | 0 | static constexpr bool monotoneIncreasing(size_t v1, size_t v2, Args... rest) { |
25 | 0 | return v1 <= v2 && monotoneIncreasing(v2, rest...); |
26 | 0 | } Unexecuted instantiation: Interpreter.cpp:bool hermes::vm::monotoneIncreasing<hermes::vm::validate_inst_layout::OpCode::$_0>(unsigned long, unsigned long, hermes::vm::validate_inst_layout::OpCode::$_0) Unexecuted instantiation: Interpreter.cpp:bool hermes::vm::monotoneIncreasing<hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0>(unsigned long, unsigned long, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0) Unexecuted instantiation: Interpreter.cpp:bool hermes::vm::monotoneIncreasing<hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0>(unsigned long, unsigned long, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0) Unexecuted instantiation: Interpreter.cpp:bool hermes::vm::monotoneIncreasing<hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0>(unsigned long, unsigned long, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0) Unexecuted instantiation: Interpreter.cpp:bool hermes::vm::monotoneIncreasing<hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0>(unsigned long, unsigned long, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0) Unexecuted instantiation: Interpreter.cpp:bool hermes::vm::monotoneIncreasing<hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0>(unsigned long, unsigned long, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0) Unexecuted instantiation: Interpreter.cpp:bool hermes::vm::monotoneIncreasing<hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0>(unsigned long, unsigned long, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0) Unexecuted instantiation: Interpreter.cpp:bool hermes::vm::monotoneIncreasing<hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0>(unsigned long, unsigned long, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0, hermes::vm::validate_inst_layout::OpCode::$_0) |
27 | | |
28 | | // Ensure that some instructions have matching layouts. |
29 | | namespace validate_inst_layout { |
30 | | |
31 | | enum OperandType { |
32 | | #define DEFINE_OPERAND_TYPE(name, ...) name, |
33 | | #include "hermes/BCGen/HBC/BytecodeList.def" |
34 | | }; |
35 | | |
36 | | enum InstOperands { |
37 | | #define DEFINE_OPCODE_0(name) name##_len = 0, |
38 | | #define DEFINE_OPCODE_1(name, op1type) \ |
39 | | name##_len = 1, name##_1 = OperandType::op1type, |
40 | | #define DEFINE_OPCODE_2(name, op1type, op2type) \ |
41 | | name##_len = 2, name##_1 = OperandType::op1type, \ |
42 | | name##_2 = OperandType::op2type, |
43 | | #define DEFINE_OPCODE_3(name, op1type, op2type, op3type) \ |
44 | | name##_len = 3, name##_1 = OperandType::op1type, \ |
45 | | name##_2 = OperandType::op2type, name##_3 = OperandType::op3type, |
46 | | #define DEFINE_OPCODE_4(name, op1type, op2type, op3type, op4type) \ |
47 | | name##_len = 4, name##_1 = OperandType::op1type, \ |
48 | | name##_2 = OperandType::op2type, name##_3 = OperandType::op3type, \ |
49 | | name##_4 = OperandType::op4type, |
50 | | #define DEFINE_OPCODE_5(name, op1type, op2type, op3type, op4type, op5type) \ |
51 | | name##_len = 5, name##_1 = OperandType::op1type, \ |
52 | | name##_2 = OperandType::op2type, name##_3 = OperandType::op3type, \ |
53 | | name##_4 = OperandType::op4type, name##_5 = OperandType::op5type, |
54 | | #define DEFINE_OPCODE_6( \ |
55 | | name, op1type, op2type, op3type, op4type, op5type, op6type) \ |
56 | | name##_len = 6, name##_1 = OperandType::op1type, \ |
57 | | name##_2 = OperandType::op2type, name##_3 = OperandType::op3type, \ |
58 | | name##_4 = OperandType::op4type, name##_5 = OperandType::op5type, \ |
59 | | name##_6 = OperandType::op6type, |
60 | | |
61 | | #include "hermes/BCGen/HBC/BytecodeList.def" |
62 | | }; |
63 | | |
64 | | #define ASSERT_LAYOUT(a, b, cond) \ |
65 | | static_assert(cond, #a " and " #b " must have the same layout") |
66 | | |
67 | | #define ASSERT_EQUAL_LAYOUT1(a, b) \ |
68 | | ASSERT_LAYOUT(a, b, a##_len >= 1 && b##_len >= 1 && a##_1 == b##_1); |
69 | | #define ASSERT_EQUAL_LAYOUT2(a, b) \ |
70 | | ASSERT_LAYOUT( \ |
71 | | a, b, a##_len >= 2 && b##_len >= 2 && a##_1 == b##_1 && a##_2 == b##_2); |
72 | | #define ASSERT_EQUAL_LAYOUT3(a, b) \ |
73 | | ASSERT_LAYOUT( \ |
74 | | a, \ |
75 | | b, \ |
76 | | a##_len >= 3 && b##_len >= 3 && a##_1 == b##_1 && a##_2 == b##_2 && \ |
77 | | a##_3 == b##_3); |
78 | | #define ASSERT_EQUAL_LAYOUT4(a, b) \ |
79 | | ASSERT_LAYOUT( \ |
80 | | a, \ |
81 | | b, \ |
82 | | a##_len >= 4 && b##_len >= 4 && a##_1 == b##_1 && a##_2 == b##_2 && \ |
83 | | a##_3 == b##_3 && a##_4 == b##_4); |
84 | | #define ASSERT_EQUAL_LAYOUT5(a, b) \ |
85 | | ASSERT_LAYOUT( \ |
86 | | a, \ |
87 | | b, \ |
88 | | a##_len >= 5 && b##_len >= 5 && a##_1 == b##_1 && a##_2 == b##_2 && \ |
89 | | a##_3 == b##_3 && a##_4 == b##_4 && a##_5 == b##_5); |
90 | | |
91 | | #include "hermes/BCGen/HBC/BytecodeList.def" |
92 | | |
93 | | #undef ASSERT_LAYOUT |
94 | | |
95 | | // Ensure the ordering of opcodes. |
96 | | namespace OpCode { |
97 | | enum { |
98 | | #define DEFINE_OPCODE_0(name, ...) name, |
99 | | #define DEFINE_OPCODE_1(name, ...) name, |
100 | | #define DEFINE_OPCODE_2(name, ...) name, |
101 | | #define DEFINE_OPCODE_3(name, ...) name, |
102 | | #define DEFINE_OPCODE_4(name, ...) name, |
103 | | #define DEFINE_OPCODE_5(name, ...) name, |
104 | | #define DEFINE_OPCODE_6(name, ...) name, |
105 | | |
106 | | #include "hermes/BCGen/HBC/BytecodeList.def" |
107 | | }; // anonymous enum |
108 | | |
109 | | #define ASSERT_MONOTONE_INCREASING(first, ...) \ |
110 | | static_assert( \ |
111 | | monotoneIncreasing(first, __VA_ARGS__), \ |
112 | | "Opcodes must be monotonically increasing"); |
113 | | |
114 | | #include "hermes/BCGen/HBC/BytecodeList.def" |
115 | | |
116 | | } // namespace OpCode |
117 | | |
118 | | } // namespace validate_inst_layout |
119 | | } // namespace vm |
120 | | } // namespace hermes |