add invariant checks
This commit is contained in:
committed by
Dan Gohman
parent
805fbb4d2a
commit
042c87763e
@@ -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);
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
Reference in New Issue
Block a user