add invariant checks

This commit is contained in:
Yury Delendik
2019-09-12 16:16:32 -05:00
committed by Dan Gohman
parent 805fbb4d2a
commit 042c87763e
5 changed files with 27 additions and 11 deletions

View File

@@ -290,7 +290,7 @@ impl Table {
match wasmtime_export { match wasmtime_export {
wasmtime_runtime::Export::Table { definition, .. } => { wasmtime_runtime::Export::Table { definition, .. } => {
let index = wasmtime_handle.table_index(unsafe { &*definition }); let index = wasmtime_handle.table_index(unsafe { &*definition });
let len = unsafe { (*definition).current_elements as u32 }; let len = unsafe { (*definition).current_elements };
for i in 0..len { for i in 0..len {
let _success = let _success =
set_table_item(&mut wasmtime_handle, &store, index, i, init.clone()); set_table_item(&mut wasmtime_handle, &store, index, i, init.clone());
@@ -335,7 +335,7 @@ impl Table {
pub fn size(&self) -> u32 { pub fn size(&self) -> u32 {
match self.wasmtime_export { match self.wasmtime_export {
wasmtime_runtime::Export::Table { definition, .. } => unsafe { wasmtime_runtime::Export::Table { definition, .. } => unsafe {
(*definition).current_elements as u32 (*definition).current_elements
}, },
_ => panic!("global definition not found"), _ => panic!("global definition not found"),
} }
@@ -346,7 +346,7 @@ impl Table {
if let Some(len) = self.wasmtime_handle.table_grow(index, delta) { if let Some(len) = self.wasmtime_handle.table_grow(index, delta) {
let mut wasmtime_handle = self.wasmtime_handle.clone(); let mut wasmtime_handle = self.wasmtime_handle.clone();
for i in 0..delta { for i in 0..delta {
let i = len as u32 - (delta - i); let i = len - (delta - i);
let _success = let _success =
set_table_item(&mut wasmtime_handle, &self.store, index, i, init.clone()); set_table_item(&mut wasmtime_handle, &self.store, index, i, init.clone());
assert!(_success); assert!(_success);

View File

@@ -45,7 +45,7 @@ pub fn layout_vmcontext(
for (index, table) in module.table_plans.iter().skip(num_tables_imports) { for (index, table) in module.table_plans.iter().skip(num_tables_imports) {
let def_index = module.defined_table_index(index).unwrap(); let def_index = module.defined_table_index(index).unwrap();
let offset = ofs.vmctx_vmtable_definition(def_index) as usize; let offset = ofs.vmctx_vmtable_definition(def_index) as usize;
let current_elements = table.table.minimum as usize; let current_elements = table.table.minimum;
unsafe { unsafe {
assert_eq!( assert_eq!(
::std::mem::size_of::<u32>() as u8, ::std::mem::size_of::<u32>() as u8,
@@ -56,7 +56,7 @@ pub fn layout_vmcontext(
.as_mut_ptr() .as_mut_ptr()
.add(offset) .add(offset)
.add(ofs.vmtable_definition_current_elements() as usize); .add(ofs.vmtable_definition_current_elements() as usize);
ptr::write(to as *mut u32, current_elements as u32); ptr::write(to as *mut u32, current_elements);
} }
table_relocs.push(TableRelocation { table_relocs.push(TableRelocation {
index: def_index.index(), index: def_index.index(),

View File

@@ -29,6 +29,12 @@ impl SignatureRegistry {
match self.signature_hash.entry(sig.clone()) { match self.signature_hash.entry(sig.clone()) {
hash_map::Entry::Occupied(entry) => *entry.get(), hash_map::Entry::Occupied(entry) => *entry.get(),
hash_map::Entry::Vacant(entry) => { hash_map::Entry::Vacant(entry) => {
// Keep `signature_hash` len under 2**32 -- VMSharedSignatureIndex::new(std::u32::MAX)
// is reserved for VMSharedSignatureIndex::default().
debug_assert!(
len < std::u32::MAX as usize,
"Invariant check: signature_hash.len() < std::u32::MAX"
);
let sig_id = VMSharedSignatureIndex::new(u32::try_from(len).unwrap()); let sig_id = VMSharedSignatureIndex::new(u32::try_from(len).unwrap());
entry.insert(sig_id); entry.insert(sig_id);
sig_id sig_id

View File

@@ -4,6 +4,7 @@
use crate::vmcontext::{VMCallerCheckedAnyfunc, VMTableDefinition}; use crate::vmcontext::{VMCallerCheckedAnyfunc, VMTableDefinition};
use cranelift_wasm::TableElementType; use cranelift_wasm::TableElementType;
use std::convert::{TryFrom, TryInto};
use std::vec::Vec; use std::vec::Vec;
use wasmtime_environ::{TablePlan, TableStyle}; use wasmtime_environ::{TablePlan, TableStyle};
@@ -23,7 +24,10 @@ impl Table {
unimplemented!("tables of types other than anyfunc ({})", ty) unimplemented!("tables of types other than anyfunc ({})", ty)
} }
}; };
assert!(
plan.table.minimum <= std::u32::MAX,
"Invariant check: vec.len() <= u32::MAX"
);
match plan.style { match plan.style {
TableStyle::CallerChecksSignature => Self { TableStyle::CallerChecksSignature => Self {
vec: vec![VMCallerCheckedAnyfunc::default(); plan.table.minimum as usize], vec: vec![VMCallerCheckedAnyfunc::default(); plan.table.minimum as usize],
@@ -34,7 +38,7 @@ impl Table {
/// Returns the number of allocated elements. /// Returns the number of allocated elements.
pub fn size(&self) -> u32 { pub fn size(&self) -> u32 {
self.vec.len() as u32 self.vec.len().try_into().unwrap()
} }
/// Grow table by the specified amount of elements. /// Grow table by the specified amount of elements.
@@ -55,8 +59,14 @@ impl Table {
return None; return None;
} }
}; };
self.vec assert!(
.resize(new_len as usize, VMCallerCheckedAnyfunc::default()); new_len <= std::u32::MAX,
"Invariant check: vec.len() <= u32::MAX"
);
self.vec.resize(
usize::try_from(new_len).unwrap(),
VMCallerCheckedAnyfunc::default(),
);
Some(new_len) Some(new_len)
} }
@@ -78,7 +88,7 @@ impl Table {
pub fn vmtable(&mut self) -> VMTableDefinition { pub fn vmtable(&mut self) -> VMTableDefinition {
VMTableDefinition { VMTableDefinition {
base: self.vec.as_mut_ptr() as *mut u8, base: self.vec.as_mut_ptr() as *mut u8,
current_elements: self.vec.len(), current_elements: self.vec.len().try_into().unwrap(),
} }
} }
} }

View File

@@ -217,7 +217,7 @@ pub struct VMTableDefinition {
pub base: *mut u8, pub base: *mut u8,
/// The current number of elements in the table. /// The current number of elements in the table.
pub current_elements: usize, pub current_elements: u32,
} }
#[cfg(test)] #[cfg(test)]