1 //! Classification of code generation errors.
2 
3 use thiserror::Error;
4 
5 /// A code generation error.
6 #[derive(Error, Debug)]
7 pub(crate) enum CodeGenError {
8     /// 32-bit platform support.
9     #[error("32-bit platforms are not supported")]
10     Unsupported32BitPlatform,
11     /// Unsupported WebAssembly type.
12     #[error("Unsupported Wasm type")]
13     UnsupportedWasmType,
14     /// Missing implementation for a current instruction.
15     #[error("Unimplemented Wasm instruction")]
16     UnimplementedWasmInstruction,
17     /// Unimplemented MacroAssembler instruction.
18     #[error("Unimplemented Masm instruction")]
19     UnimplementedMasmInstruction,
20     /// Unimplemented Wasm load kind.
21     #[error("Unimplemented Wasm load kind")]
22     UnimplementedWasmLoadKind,
23     /// Unimplemented due to requiring AVX.
24     #[error("Instruction not implemented for CPUs without AVX support")]
25     UnimplementedForNoAvx,
26     /// Unimplemented due to requiring AVX2.
27     #[error("Instruction not implemented for CPUs without AVX2 support")]
28     UnimplementedForNoAvx2,
29     /// Unimplemented due to requiring AVX512VL.
30     #[error("Instruction not implemented for CPUs without AVX512VL support")]
31     UnimplementedForNoAvx512VL,
32     /// Unimplemented due to requiring AVX512DQ.
33     #[error("Instruction not implemented for CPUs without AVX512DQ support")]
34     UnimplementedForNoAvx512DQ,
35     /// Unsupported eager initialization of tables.
36     #[error("Unsupported eager initialization of tables")]
37     UnsupportedTableEagerInit,
38     /// An internal error.
39     ///
40     /// This error means that an internal invariant was not met and usually
41     /// implies a compiler bug.
42     #[error("Winch internal error: {0}")]
43     Internal(InternalError),
44 }
45 
46 /// An internal error.
47 #[derive(Error, Debug)]
48 pub(crate) enum InternalError {
49     /// Register allocation error.
50     #[error("Expected register to be available")]
51     ExpectedRegisterToBeAvailable,
52     /// Control frame expected.
53     #[error("Expected control frame")]
54     ControlFrameExpected,
55     /// Control frame for if expected.
56     #[error("Control frame for if expected")]
57     IfControlFrameExpected,
58     /// Not enough values in the value stack.
59     #[error("Not enough values in the value stack")]
60     MissingValuesInStack,
61     /// Unexpected operand size. 32 or 64 bits are supported.
62     #[error("Unexpected operand size for operation")]
63     UnexpectedOperandSize,
64     /// Accessing the value stack with an invalid index.
65     #[error("Unexpected value stack index")]
66     UnexpectedValueStackIndex,
67     /// Expects a specific state in the value stack.
68     #[error("Unexpected value in value stack")]
69     UnexpectedValueInValueStack,
70     /// A mismatch occurred in the control frame state.
71     #[error("Mismatch in control frame state")]
72     ControlFrameStateMismatch,
73     /// Expected a specific table element value.
74     #[error("Table element value expected")]
75     TableElementValueExpected,
76     /// Illegal fuel tracking state.
77     #[error("Illegal fuel state")]
78     IllegalFuelState,
79     /// Missing special function argument.
80     #[error("Argument for `VMContext` expected")]
81     VMContextArgumentExpected,
82     /// Expected memory location to be addressed via the stack pointer.
83     #[error("Expected stack pointer addressing")]
84     SPAddressingExpected,
85     /// Stack pointer offset is illegal.
86     #[error("Invalid stack pointer offset")]
87     InvalidSPOffset,
88     /// Unexpected function call at location.
89     #[error("Unexpected function call in current context")]
90     UnexpectedFunctionCall,
91     /// Invalid local offset.
92     #[error("Invalid local offset")]
93     InvalidLocalOffset,
94     /// Unsupported immediate for instruction.
95     #[error("Unsupported immediate")]
96     UnsupportedImm,
97     /// Invalid operand combination.
98     #[error("Invalid operand combination")]
99     InvalidOperandCombination,
100     /// Invalid two argument form.
101     #[error("Invalid two argument form")]
102     InvalidTwoArgumentForm,
103 }
104 
105 impl CodeGenError {
unsupported_wasm_type() -> Self106     pub(crate) const fn unsupported_wasm_type() -> Self {
107         Self::UnsupportedWasmType
108     }
109 
unsupported_table_eager_init() -> Self110     pub(crate) const fn unsupported_table_eager_init() -> Self {
111         Self::UnsupportedTableEagerInit
112     }
113 
unimplemented_wasm_instruction() -> Self114     pub(crate) const fn unimplemented_wasm_instruction() -> Self {
115         Self::UnimplementedWasmInstruction
116     }
117 
unsupported_32_bit_platform() -> Self118     pub(crate) const fn unsupported_32_bit_platform() -> Self {
119         Self::Unsupported32BitPlatform
120     }
121 
unexpected_function_call() -> Self122     pub(crate) const fn unexpected_function_call() -> Self {
123         Self::Internal(InternalError::UnexpectedFunctionCall)
124     }
125 
sp_addressing_expected() -> Self126     pub(crate) const fn sp_addressing_expected() -> Self {
127         Self::Internal(InternalError::SPAddressingExpected)
128     }
129 
invalid_sp_offset() -> Self130     pub(crate) const fn invalid_sp_offset() -> Self {
131         Self::Internal(InternalError::InvalidSPOffset)
132     }
133 
expected_register_to_be_available() -> Self134     pub(crate) const fn expected_register_to_be_available() -> Self {
135         Self::Internal(InternalError::ExpectedRegisterToBeAvailable)
136     }
137 
vmcontext_arg_expected() -> Self138     pub(crate) fn vmcontext_arg_expected() -> Self {
139         Self::Internal(InternalError::VMContextArgumentExpected)
140     }
141 
control_frame_expected() -> Self142     pub(crate) const fn control_frame_expected() -> Self {
143         Self::Internal(InternalError::ControlFrameExpected)
144     }
145 
if_control_frame_expected() -> Self146     pub(crate) const fn if_control_frame_expected() -> Self {
147         Self::Internal(InternalError::IfControlFrameExpected)
148     }
149 
missing_values_in_stack() -> Self150     pub(crate) const fn missing_values_in_stack() -> Self {
151         Self::Internal(InternalError::MissingValuesInStack)
152     }
153 
unexpected_operand_size() -> Self154     pub(crate) const fn unexpected_operand_size() -> Self {
155         Self::Internal(InternalError::UnexpectedOperandSize)
156     }
157 
unexpected_value_stack_index() -> Self158     pub(crate) const fn unexpected_value_stack_index() -> Self {
159         Self::Internal(InternalError::UnexpectedValueStackIndex)
160     }
161 
unexpected_value_in_value_stack() -> Self162     pub(crate) const fn unexpected_value_in_value_stack() -> Self {
163         Self::Internal(InternalError::UnexpectedValueInValueStack)
164     }
165 
control_frame_state_mismatch() -> Self166     pub(crate) const fn control_frame_state_mismatch() -> Self {
167         Self::Internal(InternalError::ControlFrameStateMismatch)
168     }
169 
table_element_value_expected() -> Self170     pub(crate) const fn table_element_value_expected() -> Self {
171         Self::Internal(InternalError::TableElementValueExpected)
172     }
173 
illegal_fuel_state() -> Self174     pub(crate) const fn illegal_fuel_state() -> Self {
175         Self::Internal(InternalError::IllegalFuelState)
176     }
177 
invalid_local_offset() -> Self178     pub(crate) const fn invalid_local_offset() -> Self {
179         Self::Internal(InternalError::InvalidLocalOffset)
180     }
181 
unsupported_imm() -> Self182     pub(crate) const fn unsupported_imm() -> Self {
183         Self::Internal(InternalError::UnsupportedImm)
184     }
185 
invalid_two_arg_form() -> Self186     pub(crate) const fn invalid_two_arg_form() -> Self {
187         Self::Internal(InternalError::InvalidTwoArgumentForm)
188     }
189 
invalid_operand_combination() -> Self190     pub(crate) const fn invalid_operand_combination() -> Self {
191         Self::Internal(InternalError::InvalidOperandCombination)
192     }
193 
unimplemented_masm_instruction() -> Self194     pub(crate) const fn unimplemented_masm_instruction() -> Self {
195         Self::UnimplementedMasmInstruction
196     }
197 }
198