/src/wasm-tools/crates/wasmparser/src/error.rs
Line | Count | Source |
1 | | use core::fmt; |
2 | | |
3 | | use crate::WasmFeatures; |
4 | | use crate::prelude::*; |
5 | | |
6 | | /// A binary reader for WebAssembly modules. |
7 | | #[derive(Debug, Clone)] |
8 | | pub struct Error { |
9 | | // Wrap the actual error data in a `Box` so that the error is just one |
10 | | // word. This means that we can continue returning small `Result`s in |
11 | | // registers. |
12 | | pub(crate) inner: Box<ErrorInner>, |
13 | | } |
14 | | |
15 | | #[derive(Debug, Clone)] |
16 | | pub(crate) struct ErrorInner { |
17 | | message: String, |
18 | | kind: ErrorKind, |
19 | | offset: u64, |
20 | | needed_hint: Option<usize>, |
21 | | } |
22 | | |
23 | | #[derive(Debug, Clone, Copy)] |
24 | | pub(crate) enum ErrorKind { |
25 | | Uncategorized, |
26 | | InvalidHeapType, |
27 | | WasmFeature(WasmFeatures), |
28 | | } |
29 | | |
30 | | /// The result for `BinaryReader` operations. |
31 | | pub type Result<T, E = Error> = core::result::Result<T, E>; |
32 | | |
33 | | impl core::error::Error for Error {} |
34 | | |
35 | | impl fmt::Display for Error { |
36 | 57 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
37 | 57 | write!( |
38 | 57 | f, |
39 | | "{} (at offset 0x{:x})", |
40 | | self.inner.message, self.inner.offset |
41 | | ) |
42 | 57 | } |
43 | | } |
44 | | |
45 | | impl Error { |
46 | | #[cold] |
47 | 3.01M | pub(crate) fn _new(kind: ErrorKind, message: String, offset: u64) -> Self { |
48 | 3.01M | Error { |
49 | 3.01M | inner: Box::new(ErrorInner { |
50 | 3.01M | kind, |
51 | 3.01M | message, |
52 | 3.01M | offset, |
53 | 3.01M | needed_hint: None, |
54 | 3.01M | }), |
55 | 3.01M | } |
56 | 3.01M | } |
57 | | |
58 | | #[cold] |
59 | 3.01M | pub(crate) fn new(message: impl Into<String>, offset: u64) -> Self { |
60 | 3.01M | Self::_new(ErrorKind::Uncategorized, message.into(), offset) |
61 | 3.01M | } <wasmparser::error::Error>::new::<alloc::string::String> Line | Count | Source | 59 | 593 | pub(crate) fn new(message: impl Into<String>, offset: u64) -> Self { | 60 | 593 | Self::_new(ErrorKind::Uncategorized, message.into(), offset) | 61 | 593 | } |
Unexecuted instantiation: <wasmparser::error::Error>::new::<&alloc::string::String> <wasmparser::error::Error>::new::<&str> Line | Count | Source | 59 | 3.01M | pub(crate) fn new(message: impl Into<String>, offset: u64) -> Self { | 60 | 3.01M | Self::_new(ErrorKind::Uncategorized, message.into(), offset) | 61 | 3.01M | } |
|
62 | | |
63 | | #[cold] |
64 | 2 | pub(crate) fn invalid_heap_type(msg: &'static str, offset: u64) -> Self { |
65 | 2 | Self::_new(ErrorKind::InvalidHeapType, msg.into(), offset) |
66 | 2 | } |
67 | | |
68 | | #[cold] |
69 | 0 | pub(crate) fn wasm_feature( |
70 | 0 | feature: crate::WasmFeatures, |
71 | 0 | msg: impl fmt::Display, |
72 | 0 | offset: u64, |
73 | 0 | ) -> Self { |
74 | 0 | Self::_new(ErrorKind::WasmFeature(feature), msg.to_string(), offset) |
75 | 0 | } Unexecuted instantiation: <wasmparser::error::Error>::wasm_feature::<core::fmt::Arguments> Unexecuted instantiation: <wasmparser::error::Error>::wasm_feature::<&str> |
76 | | |
77 | | #[cold] |
78 | 496 | pub(crate) fn fmt(args: fmt::Arguments<'_>, offset: u64) -> Self { |
79 | 496 | Error::new(args.to_string(), offset) |
80 | 496 | } |
81 | | |
82 | | #[cold] |
83 | 3.01M | pub(crate) fn eof(offset: u64, needed_hint: usize) -> Self { |
84 | 3.01M | let mut err = Error::new("unexpected end-of-file", offset); |
85 | 3.01M | err.inner.needed_hint = Some(needed_hint); |
86 | 3.01M | err |
87 | 3.01M | } |
88 | | |
89 | 4 | pub(crate) fn kind(&self) -> ErrorKind { |
90 | 4 | self.inner.kind |
91 | 4 | } |
92 | | |
93 | | /// Get this error's message. |
94 | 146 | pub fn message(&self) -> &str { |
95 | 146 | &self.inner.message |
96 | 146 | } |
97 | | |
98 | | /// Get the offset within the Wasm binary where the error occurred. |
99 | 146 | pub fn offset(&self) -> u64 { |
100 | 146 | self.inner.offset |
101 | 146 | } |
102 | | |
103 | | /// Returns `Some` if this error is due to a disabled Wasm feature. |
104 | | /// |
105 | | /// If the `features` crate feature is enabled, a returned [`WasmFeatures`] |
106 | | /// will contain a feature that could be enabled to prevent this error. |
107 | | /// |
108 | | /// **Note:** This is not comprehensive; `None` may be returned in some |
109 | | /// cases where enabling a feature could avoid the error. |
110 | 0 | pub fn missing_wasm_feature(&self) -> Option<WasmFeatures> { |
111 | 0 | match self.inner.kind { |
112 | 0 | ErrorKind::WasmFeature(features) => Some(features), |
113 | 0 | _ => None, |
114 | | } |
115 | 0 | } |
116 | | |
117 | | #[cfg(all(feature = "validate", feature = "component-model"))] |
118 | 0 | pub(crate) fn add_context(&mut self, context: String) { |
119 | 0 | self.inner.message = format!("{context}\n{}", self.inner.message); |
120 | 0 | } |
121 | | |
122 | 4 | pub(crate) fn set_message(&mut self, message: impl Into<String>) { |
123 | 4 | self.inner.message = message.into(); |
124 | 4 | } |
125 | | |
126 | 1.57M | pub(crate) fn needed_hint(&self) -> Option<usize> { |
127 | 1.57M | self.inner.needed_hint |
128 | 1.57M | } |
129 | | |
130 | 0 | pub(crate) fn without_needed_hint(mut self) -> Self { |
131 | 0 | self.inner.needed_hint = None; |
132 | 0 | self |
133 | 0 | } |
134 | | } |