@@ -19,9 +19,58 @@ use core::{
19
19
cmp,
20
20
fmt:: { self , Display } ,
21
21
} ;
22
+ use std:: vec:: Vec ;
23
+
24
+ /// A non-empty list of [`Error`]s.
25
+ pub struct ErrorList < ' ctx > {
26
+ ctx : ErrorContext < ' ctx > ,
27
+ errors : Vec < Error > ,
28
+ }
29
+
30
+ impl < ' ctx > ErrorList < ' ctx > {
31
+ /// Creates a new [`ErrorList`].
32
+ ///
33
+ /// # Panics
34
+ ///
35
+ /// If `errors` is empty.
36
+ fn new ( ctx : ErrorContext < ' ctx > , errors : Vec < Error > ) -> Self {
37
+ assert ! ( !errors. is_empty( ) ) ;
38
+ Self { ctx, errors }
39
+ }
40
+ }
41
+
42
+ impl ErrorList < ' _ > {
43
+ /// Returns `true` if `self` contains at least one [`Error`].
44
+ fn has_errors ( & self ) -> bool {
45
+ !self . errors . is_empty ( )
46
+ }
47
+
48
+ /// Returns the number of [`Error`]s in `self`.
49
+ fn len_errors ( & self ) -> usize {
50
+ self . errors . len ( )
51
+ }
52
+ }
53
+
54
+ impl Display for ErrorList < ' _ > {
55
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
56
+ if !self . has_errors ( ) {
57
+ return writeln ! ( f, "all checked Wasmi translation invariants are uphold" ) ;
58
+ }
59
+ writeln ! (
60
+ f,
61
+ "encountered {} broken invariants for Wasmi translation:" ,
62
+ self . len_errors( )
63
+ ) ?;
64
+ let ctx = self . ctx ;
65
+ for ( n, error) in self . errors . iter ( ) . cloned ( ) . enumerate ( ) {
66
+ write ! ( f, "error({n}): {}" , ErrorWithContext { ctx, error } ) ?;
67
+ }
68
+ Ok ( ( ) )
69
+ }
70
+ }
22
71
23
72
/// An error describing a broken Wasmi translation invariant.
24
- #[ derive( Debug ) ]
73
+ #[ derive( Debug , Clone ) ]
25
74
pub struct Error {
26
75
/// The erraneous `Instruction` index.
27
76
instr : Instr ,
@@ -30,7 +79,7 @@ pub struct Error {
30
79
}
31
80
32
81
/// The reason behind a broken Wasmi translation invariant.
33
- #[ derive( Debug ) ]
82
+ #[ derive( Debug , Clone ) ]
34
83
pub enum Reason {
35
84
InvalidRegister {
36
85
/// The invalid `Reg`.
@@ -216,6 +265,7 @@ pub struct ErrorWithContext<'ctx> {
216
265
}
217
266
218
267
/// A context to populate an [`Error`] with more information for its [`Display`] implementation.
268
+ #[ derive( Copy , Clone ) ]
219
269
pub struct ErrorContext < ' ctx > {
220
270
/// The underlying Wasmi function translator that has already finished its job.
221
271
translator : & ' ctx FuncTranslator ,
@@ -286,15 +336,8 @@ impl ErrorWithContext<'_> {
286
336
/// # Errors
287
337
///
288
338
/// If a Wasmi translation invariant is broken.
289
- pub fn verify_translation_invariants ( translator : & FuncTranslator ) -> Result < ( ) , ErrorWithContext > {
290
- let checker = TranslationInvariantsChecker { translator } ;
291
- match checker. verify_translation_invariants ( ) {
292
- Ok ( _) => Ok ( ( ) ) ,
293
- Err ( error) => {
294
- let ctx = ErrorContext { translator } ;
295
- Err ( ErrorWithContext { ctx, error } )
296
- }
297
- }
339
+ pub fn verify_translation_invariants ( translator : & FuncTranslator ) -> Result < ( ) , ErrorList > {
340
+ TranslationInvariantsChecker { translator } . verify_translation_invariants ( )
298
341
}
299
342
300
343
/// Encapsulates state required for translation invariants checking.
@@ -303,15 +346,25 @@ struct TranslationInvariantsChecker<'translator> {
303
346
translator : & ' translator FuncTranslator ,
304
347
}
305
348
306
- impl TranslationInvariantsChecker < ' _ > {
349
+ impl < ' translator > TranslationInvariantsChecker < ' translator > {
307
350
/// Checks if the invariants of Wasmi function translation are uphold.
308
351
///
309
352
/// Read more here: [`verify_translation_invariants`]
310
353
///
311
354
/// # Errors
312
355
///
313
356
/// If a Wasmi translation invariant is broken.
314
- fn verify_translation_invariants ( & self ) -> Result < ( ) , Error > {
315
- todo ! ( )
357
+ fn verify_translation_invariants ( & self ) -> Result < ( ) , ErrorList < ' translator > > {
358
+ let errors = Vec :: new ( ) ;
359
+ // TODO: perform invariant checking
360
+ if errors. is_empty ( ) {
361
+ return Ok ( ( ) ) ;
362
+ }
363
+ Err ( ErrorList :: new (
364
+ ErrorContext {
365
+ translator : self . translator ,
366
+ } ,
367
+ errors,
368
+ ) )
316
369
}
317
370
}
0 commit comments