winch_codegen/codegen/
error.rs

1//! Classification of code generation errors.
2
3use thiserror::Error;
4
5/// A code generation error.
6#[derive(Error, Debug)]
7pub(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)]
48pub(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 occured 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
105impl CodeGenError {
106    pub(crate) const fn unsupported_wasm_type() -> Self {
107        Self::UnsupportedWasmType
108    }
109
110    pub(crate) const fn unsupported_table_eager_init() -> Self {
111        Self::UnsupportedTableEagerInit
112    }
113
114    pub(crate) const fn unimplemented_wasm_instruction() -> Self {
115        Self::UnimplementedWasmInstruction
116    }
117
118    pub(crate) const fn unsupported_32_bit_platform() -> Self {
119        Self::Unsupported32BitPlatform
120    }
121
122    pub(crate) const fn unexpected_function_call() -> Self {
123        Self::Internal(InternalError::UnexpectedFunctionCall)
124    }
125
126    pub(crate) const fn sp_addressing_expected() -> Self {
127        Self::Internal(InternalError::SPAddressingExpected)
128    }
129
130    pub(crate) const fn invalid_sp_offset() -> Self {
131        Self::Internal(InternalError::InvalidSPOffset)
132    }
133
134    pub(crate) const fn expected_register_to_be_available() -> Self {
135        Self::Internal(InternalError::ExpectedRegisterToBeAvailable)
136    }
137
138    pub(crate) fn vmcontext_arg_expected() -> Self {
139        Self::Internal(InternalError::VMContextArgumentExpected)
140    }
141
142    pub(crate) const fn control_frame_expected() -> Self {
143        Self::Internal(InternalError::ControlFrameExpected)
144    }
145
146    pub(crate) const fn if_control_frame_expected() -> Self {
147        Self::Internal(InternalError::IfControlFrameExpected)
148    }
149
150    pub(crate) const fn missing_values_in_stack() -> Self {
151        Self::Internal(InternalError::MissingValuesInStack)
152    }
153
154    pub(crate) const fn unexpected_operand_size() -> Self {
155        Self::Internal(InternalError::UnexpectedOperandSize)
156    }
157
158    pub(crate) const fn unexpected_value_stack_index() -> Self {
159        Self::Internal(InternalError::UnexpectedValueStackIndex)
160    }
161
162    pub(crate) const fn unexpected_value_in_value_stack() -> Self {
163        Self::Internal(InternalError::UnexpectedValueInValueStack)
164    }
165
166    pub(crate) const fn control_frame_state_mismatch() -> Self {
167        Self::Internal(InternalError::ControlFrameStateMismatch)
168    }
169
170    pub(crate) const fn table_element_value_expected() -> Self {
171        Self::Internal(InternalError::TableElementValueExpected)
172    }
173
174    pub(crate) const fn illegal_fuel_state() -> Self {
175        Self::Internal(InternalError::IllegalFuelState)
176    }
177
178    pub(crate) const fn invalid_local_offset() -> Self {
179        Self::Internal(InternalError::InvalidLocalOffset)
180    }
181
182    pub(crate) const fn unsupported_imm() -> Self {
183        Self::Internal(InternalError::UnsupportedImm)
184    }
185
186    pub(crate) const fn invalid_two_arg_form() -> Self {
187        Self::Internal(InternalError::InvalidTwoArgumentForm)
188    }
189
190    pub(crate) const fn invalid_operand_combination() -> Self {
191        Self::Internal(InternalError::InvalidOperandCombination)
192    }
193
194    pub(crate) const fn unimplemented_masm_instruction() -> Self {
195        Self::UnimplementedMasmInstruction
196    }
197}