Rewrite interpreter generically (#2323)

* Rewrite interpreter generically

This change re-implements the Cranelift interpreter to use generic values; this makes it possible to do abstract interpretation of Cranelift instructions. In doing so, the interpretation state is extracted from the `Interpreter` structure and is accessed via a `State` trait; this makes it possible to not only more clearly observe the interpreter's state but also to interpret using a dummy state (e.g. `ImmutableRegisterState`). This addition made it possible to implement more of the Cranelift instructions (~70%, ignoring the x86-specific instructions).

* Replace macros with closures
This commit is contained in:
Andrew Brown
2020-11-02 12:28:07 -08:00
committed by GitHub
parent 59a2ce4d34
commit 6d50099816
16 changed files with 1590 additions and 342 deletions

View File

@@ -32,16 +32,16 @@ impl<'a> Frame<'a> {
/// Retrieve the actual value associated with an SSA reference.
#[inline]
pub fn get(&self, name: &ValueRef) -> &DataValue {
pub fn get(&self, name: ValueRef) -> &DataValue {
trace!("Get {}", name);
self.registers
.get(name)
.get(&name)
.unwrap_or_else(|| panic!("unknown value: {}", name))
}
/// Retrieve multiple SSA references; see `get`.
pub fn get_all(&self, names: &[ValueRef]) -> Vec<DataValue> {
names.iter().map(|r| self.get(r)).cloned().collect()
names.iter().map(|r| self.get(*r)).cloned().collect()
}
/// Assign `value` to the SSA reference `name`.
@@ -108,7 +108,7 @@ mod tests {
let a = ValueRef::with_number(1).unwrap();
let fortytwo = DataValue::I32(42);
frame.set(a, fortytwo.clone());
assert_eq!(frame.get(&a), &fortytwo);
assert_eq!(frame.get(a), &fortytwo);
}
#[test]
@@ -118,6 +118,6 @@ mod tests {
let frame = Frame::new(&func);
let a = ValueRef::with_number(1).unwrap();
frame.get(&a);
frame.get(a);
}
}