This commit is contained in:
Guanqun Lu 2018-09-20 07:43:33 +00:00 committed by GitHub
commit 49282591c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 71 additions and 5 deletions

View File

@ -1109,11 +1109,7 @@ impl FunctionContext {
.map(RuntimeValue::default)
.collect::<Vec<_>>();
// TODO: Replace with extend.
for local in locals {
value_stack.push(local)
.map_err(|_| TrapKind::StackOverflow)?;
}
value_stack.extend(&locals)?;
self.is_initialized = true;
Ok(())
@ -1263,8 +1259,78 @@ impl ValueStack {
Ok(())
}
#[inline]
fn extend(&mut self, values: &[RuntimeValue]) -> Result<(), TrapKind> {
let avail_len = self.buf.len() - self.sp;
let to_copy_len = values.len();
if to_copy_len <= avail_len {
self.buf[self.sp..(self.sp+to_copy_len)].copy_from_slice(&values[..to_copy_len]);
self.sp += to_copy_len;
Ok(())
} else {
Err(TrapKind::StackOverflow)
}
}
#[inline]
fn len(&self) -> usize {
self.sp
}
}
#[cfg(test)]
mod tests {
use super::ValueStack;
use value::RuntimeValue;
#[test]
fn test_stack_extend() {
let mut stack = ValueStack::with_limit(5);
let values = vec![
RuntimeValue::I32(1),
RuntimeValue::I32(2),
RuntimeValue::I32(3),
RuntimeValue::I32(4),
RuntimeValue::I32(5)
];
assert!(stack.extend(&values).is_ok());
assert_eq!(stack.len(), 5);
assert!(stack.push(RuntimeValue::I32(6)).is_err());
// check each elements
assert_eq!(stack.pop(), RuntimeValue::I32(5));
assert_eq!(stack.pop(), RuntimeValue::I32(4));
assert_eq!(stack.pop(), RuntimeValue::I32(3));
assert_eq!(stack.pop(), RuntimeValue::I32(2));
assert_eq!(stack.pop(), RuntimeValue::I32(1));
assert_eq!(stack.len(), 0);
}
#[test]
fn test_stack_extend_overflow() {
let mut stack = ValueStack::with_limit(4);
let values = vec![
RuntimeValue::I32(1),
RuntimeValue::I32(2),
RuntimeValue::I32(3),
RuntimeValue::I32(4),
RuntimeValue::I32(5)
];
assert!(stack.extend(&values).is_err());
assert_eq!(stack.len(), 0);
assert!(stack.push(RuntimeValue::I32(6)).is_ok());
assert_eq!(stack.len(), 1);
// check each elements
assert_eq!(stack.pop(), RuntimeValue::I32(6));
assert_eq!(stack.len(), 0);
}
}