ISLE: Fix a bug with extractor ordering (#4661)
https://github.com/bytecodealliance/wasmtime/pull/4661 Co-authored-by: Chris Fallin <chris@cfallin.org>
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
(type u32 (primitive u32))
|
||||||
|
|
||||||
|
(decl identity (u32) u32)
|
||||||
|
(extern extractor infallible identity identity)
|
||||||
|
|
||||||
|
(decl is_zero (u32) u32)
|
||||||
|
(extern extractor is_zero is_zero)
|
||||||
|
|
||||||
|
(decl test (u32) u32)
|
||||||
|
|
||||||
|
;; This exposes a bug where infallible extractors were running before fallible
|
||||||
|
;; ones, as the derived ordering for the `Extract` type was ordering them ahead
|
||||||
|
;; of the fallible ones. The result is that the fallible `is_zero` extractor
|
||||||
|
;; never runs, as the `identity` extractor will always succeed before it's
|
||||||
|
;; called.
|
||||||
|
(rule (test (identity x)) x)
|
||||||
|
|
||||||
|
(rule (test (is_zero x)) 2)
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
mod extractor_ordering_bug;
|
||||||
|
|
||||||
|
struct Context;
|
||||||
|
impl extractor_ordering_bug::Context for Context {
|
||||||
|
fn is_zero(&mut self, val: u32) -> Option<u32> {
|
||||||
|
if val == 0 {
|
||||||
|
Some(val)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn identity(&mut self, val: u32) -> u32 {
|
||||||
|
val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut ctx = Context;
|
||||||
|
|
||||||
|
assert_eq!(extractor_ordering_bug::constructor_test(&mut ctx, 0), Some(2));
|
||||||
|
assert_eq!(extractor_ordering_bug::constructor_test(&mut ctx, 1), Some(1));
|
||||||
|
}
|
||||||
@@ -94,6 +94,9 @@ pub enum PatternInst {
|
|||||||
/// value to extract, the other are the `Input`-polarity extractor args) and
|
/// value to extract, the other are the `Input`-polarity extractor args) and
|
||||||
/// producing an output value for each `Output`-polarity extractor arg.
|
/// producing an output value for each `Output`-polarity extractor arg.
|
||||||
Extract {
|
Extract {
|
||||||
|
/// Whether this extraction is infallible or not. `false`
|
||||||
|
/// comes before `true`, so fallible nodes come first.
|
||||||
|
infallible: bool,
|
||||||
/// The value to extract, followed by polarity extractor args.
|
/// The value to extract, followed by polarity extractor args.
|
||||||
inputs: Vec<Value>,
|
inputs: Vec<Value>,
|
||||||
/// The types of the inputs.
|
/// The types of the inputs.
|
||||||
@@ -102,8 +105,6 @@ pub enum PatternInst {
|
|||||||
output_tys: Vec<TypeId>,
|
output_tys: Vec<TypeId>,
|
||||||
/// This extractor's term.
|
/// This extractor's term.
|
||||||
term: TermId,
|
term: TermId,
|
||||||
/// Whether this extraction is infallible or not.
|
|
||||||
infallible: bool,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// NB: This has to go last, since it is infallible, so that when we sort
|
// NB: This has to go last, since it is infallible, so that when we sort
|
||||||
|
|||||||
Reference in New Issue
Block a user