Struct evmil::dfa::AbstractStack
source · pub struct AbstractStack { /* private fields */ }
Implementations§
source§impl AbstractStack
impl AbstractStack
sourcepub fn new<T: Into<Interval>>(lower: T, upper: Vec<AbstractValue>) -> Self
pub fn new<T: Into<Interval>>(lower: T, upper: Vec<AbstractValue>) -> Self
Examples found in repository?
src/dfa/stack.rs (line 179)
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
pub fn merge(self, other: &AbstractStack) -> Self {
let slen = self.upper.len();
let olen = other.upper.len();
// Determine common upper length
let n = cmp::min(slen,olen);
// Normalise lower segments
let lself = self.lower.add(slen - n);
let lother = other.lower.add(olen - n);
let mut merger = AbstractStack::new(lself.union(&lother),Vec::new());
// Push merged items from upper segment
for i in (0..n).rev() {
let ithself = self.peek(i);
let ithother = other.peek(i);
merger = merger.push(ithself.merge(ithother));
}
// Done
merger
}
sourcepub fn is_bottom(&self) -> bool
pub fn is_bottom(&self) -> bool
Examples found in repository?
src/cfa.rs (line 37)
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
pub fn is_bottom(&self) -> bool {
self.stack.is_bottom()
}
pub fn len(&self) -> Interval {
self.stack.len()
}
pub fn push(self, val: AbstractValue) -> Self {
CfaState::new(self.stack.push(val))
}
pub fn pop(mut self, n: usize) -> Self {
assert!(n > 0);
let mut stack = self.stack;
for i in 0..n {
stack = stack.pop();
}
CfaState::new(stack)
}
pub fn set(self, n:usize, val: AbstractValue) -> Self {
CfaState::new(self.stack.set(n,val))
}
}
impl Clone for CfaState {
fn clone(&self) -> Self {
CfaState::new(self.stack.clone())
}
}
impl fmt::Display for CfaState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,"{}",self.stack)
}
}
impl AbstractState for CfaState {
fn is_reachable(&self) -> bool { !self.stack.is_bottom() }
More examples
src/dfa/stack.rs (line 113)
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
pub fn push(mut self, val: AbstractValue) -> Self {
// Should never be called on bottom
assert!(!self.is_bottom());
//
if val == AbstractValue::Unknown && self.upper.len() == 0 {
self.lower = self.lower.add(1);
} else {
// Pop target address off the stack.
self.upper.push(val);
}
// Done
self
}
/// Pop an item of this stack, producing an updated state.
pub fn pop(mut self) -> Self {
// Should never be called on bottom
assert!(!self.is_bottom());
// Pop target address off the stack.
if self.upper.is_empty() {
self.lower = self.lower.sub(1);
} else {
self.upper.pop();
}
// Done
self
}
/// Perk nth item on the stack (where `0` is top).
pub fn peek(&self, n: usize) -> AbstractValue {
// Should never be called on bottom
assert!(!self.is_bottom());
// Get the nth value!
if n < self.upper.len() {
// Determine stack index
let i = self.upper.len() - (1+n);
// Extract value
self.upper[i]
} else {
AbstractValue::Unknown
}
}
/// Set specific item on this stack.
pub fn set(mut self, n: usize, val: AbstractValue) -> Self {
// Should never be called on bottom
assert!(!self.is_bottom());
if n < self.upper.len() {
// Determine stack index
let i = self.upper.len() - (1+n);
// Set value
self.upper[i] = val;
// Done
self
} else {
// This case is complicated because we need to expand the
// upper portion to include the new value (where
// possible).
todo!("Implement me!");
}
}
sourcepub fn min_len(&self) -> usize
pub fn min_len(&self) -> usize
Determine the minimum length of any stack represented by this abstract stack.
sourcepub fn max_len(&self) -> usize
pub fn max_len(&self) -> usize
Determine the maximum length of any stack represented by this abstract stack.
sourcepub fn push(self, val: AbstractValue) -> Self
pub fn push(self, val: AbstractValue) -> Self
Push an iterm onto this stack.
Examples found in repository?
More examples
src/dfa/stack.rs (line 184)
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
pub fn merge(self, other: &AbstractStack) -> Self {
let slen = self.upper.len();
let olen = other.upper.len();
// Determine common upper length
let n = cmp::min(slen,olen);
// Normalise lower segments
let lself = self.lower.add(slen - n);
let lother = other.lower.add(olen - n);
let mut merger = AbstractStack::new(lself.union(&lother),Vec::new());
// Push merged items from upper segment
for i in (0..n).rev() {
let ithself = self.peek(i);
let ithother = other.peek(i);
merger = merger.push(ithself.merge(ithother));
}
// Done
merger
}
sourcepub fn peek(&self, n: usize) -> AbstractValue
pub fn peek(&self, n: usize) -> AbstractValue
Perk nth item on the stack (where 0
is top).
Examples found in repository?
More examples
src/dfa/stack.rs (line 182)
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
pub fn merge(self, other: &AbstractStack) -> Self {
let slen = self.upper.len();
let olen = other.upper.len();
// Determine common upper length
let n = cmp::min(slen,olen);
// Normalise lower segments
let lself = self.lower.add(slen - n);
let lother = other.lower.add(olen - n);
let mut merger = AbstractStack::new(lself.union(&lother),Vec::new());
// Push merged items from upper segment
for i in (0..n).rev() {
let ithself = self.peek(i);
let ithother = other.peek(i);
merger = merger.push(ithself.merge(ithother));
}
// Done
merger
}
sourcepub fn set(self, n: usize, val: AbstractValue) -> Self
pub fn set(self, n: usize, val: AbstractValue) -> Self
Set specific item on this stack.
sourcepub fn merge(self, other: &AbstractStack) -> Self
pub fn merge(self, other: &AbstractStack) -> Self
Merge two abstract stacks together.
sourcepub fn merge_into(&mut self, other: &AbstractStack) -> bool
pub fn merge_into(&mut self, other: &AbstractStack) -> bool
Merge an abstract stack into this stack, whilst reporting whether this stack changed or not.
Examples found in repository?
src/cfa.rs (line 94)
87 88 89 90 91 92 93 94 95 96 97 98 99
fn merge(&mut self, other: Self) -> bool {
if *self != other {
if !other.is_bottom() {
if self.is_bottom() {
*self = other;
return true;
} else {
return self.stack.merge_into(&other.stack);
}
}
}
false
}
Trait Implementations§
source§impl Clone for AbstractStack
impl Clone for AbstractStack
source§impl Debug for AbstractStack
impl Debug for AbstractStack
source§impl Display for AbstractStack
impl Display for AbstractStack
source§impl PartialEq<AbstractStack> for AbstractStack
impl PartialEq<AbstractStack> for AbstractStack
source§fn eq(&self, other: &AbstractStack) -> bool
fn eq(&self, other: &AbstractStack) -> bool
This method tests for
self
and other
values to be equal, and is used
by ==
.