Skip to main content

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 due to requiring AVX.
21    #[error("Instruction not implemented for CPUs without AVX support")]
22    UnimplementedForNoAvx,
23    /// Unimplemented due to requiring AVX2.
24    #[error("Instruction not implemented for CPUs without AVX2 support")]
25    UnimplementedForNoAvx2,
26    /// Unimplemented due to requiring AVX512VL.
27    #[error("Instruction not implemented for CPUs without AVX512VL support")]
28    UnimplementedForNoAvx512VL,
29    /// Unimplemented due to requiring AVX512DQ.
30    #[error("Instruction not implemented for CPUs without AVX512DQ support")]
31    UnimplementedForNoAvx512DQ,
32    /// Unsupported eager initialization of tables.
33    #[error("Unsupported eager initialization of tables")]
34    UnsupportedTableEagerInit,
35    /// An allocation is too large to represent.
36    #[error("Allocation size is too large")]
37    AllocationTooLarge,
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 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    /// Invalid operand combination.
95    #[error("Invalid operand combination")]
96    InvalidOperandCombination,
97    /// Invalid two argument form.
98    #[error("Invalid two argument form")]
99    InvalidTwoArgumentForm,
100}
101
102impl CodeGenError {
103    pub(crate) const fn unsupported_wasm_type() -> Self {
104        Self::UnsupportedWasmType
105    }
106
107    pub(crate) const fn unsupported_table_eager_init() -> Self {
108        Self::UnsupportedTableEagerInit
109    }
110
111    pub(crate) const fn unimplemented_wasm_instruction() -> Self {
112        Self::UnimplementedWasmInstruction
113    }
114
115    pub(crate) const fn unsupported_32_bit_platform() -> Self {
116        Self::Unsupported32BitPlatform
117    }
118
119    pub(crate) const fn allocation_too_large() -> Self {
120        Self::AllocationTooLarge
121    }
122
123    pub(crate) const fn unexpected_function_call() -> Self {
124        Self::Internal(InternalError::UnexpectedFunctionCall)
125    }
126
127    pub(crate) const fn sp_addressing_expected() -> Self {
128        Self::Internal(InternalError::SPAddressingExpected)
129    }
130
131    pub(crate) const fn invalid_sp_offset() -> Self {
132        Self::Internal(InternalError::InvalidSPOffset)
133    }
134
135    pub(crate) const fn expected_register_to_be_available() -> Self {
136        Self::Internal(InternalError::ExpectedRegisterToBeAvailable)
137    }
138
139    pub(crate) fn vmcontext_arg_expected() -> Self {
140        Self::Internal(InternalError::VMContextArgumentExpected)
141    }
142
143    pub(crate) const fn control_frame_expected() -> Self {
144        Self::Internal(InternalError::ControlFrameExpected)
145    }
146
147    pub(crate) const fn if_control_frame_expected() -> Self {
148        Self::Internal(InternalError::IfControlFrameExpected)
149    }
150
151    pub(crate) const fn missing_values_in_stack() -> Self {
152        Self::Internal(InternalError::MissingValuesInStack)
153    }
154
155    pub(crate) const fn unexpected_operand_size() -> Self {
156        Self::Internal(InternalError::UnexpectedOperandSize)
157    }
158
159    pub(crate) const fn unexpected_value_stack_index() -> Self {
160        Self::Internal(InternalError::UnexpectedValueStackIndex)
161    }
162
163    pub(crate) const fn unexpected_value_in_value_stack() -> Self {
164        Self::Internal(InternalError::UnexpectedValueInValueStack)
165    }
166
167    pub(crate) const fn control_frame_state_mismatch() -> Self {
168        Self::Internal(InternalError::ControlFrameStateMismatch)
169    }
170
171    pub(crate) const fn table_element_value_expected() -> Self {
172        Self::Internal(InternalError::TableElementValueExpected)
173    }
174
175    pub(crate) const fn illegal_fuel_state() -> Self {
176        Self::Internal(InternalError::IllegalFuelState)
177    }
178
179    pub(crate) const fn invalid_local_offset() -> Self {
180        Self::Internal(InternalError::InvalidLocalOffset)
181    }
182
183    pub(crate) const fn invalid_two_arg_form() -> Self {
184        Self::Internal(InternalError::InvalidTwoArgumentForm)
185    }
186
187    pub(crate) const fn invalid_operand_combination() -> Self {
188        Self::Internal(InternalError::InvalidOperandCombination)
189    }
190
191    pub(crate) const fn unimplemented_masm_instruction() -> Self {
192        Self::UnimplementedMasmInstruction
193    }
194}