Clippy fixes (#692)

This commit is contained in:
XAMPPRocky
2019-12-24 20:50:07 +00:00
committed by Dan Gohman
parent 6c97cfed1e
commit 907e7aac01
35 changed files with 390 additions and 417 deletions

View File

@@ -167,7 +167,7 @@ impl Func {
} else { } else {
panic!("expected function export") panic!("expected function export")
}; };
let callable = WasmtimeFn::new(store, instance_handle, export.clone()); let callable = WasmtimeFn::new(store, instance_handle, export);
Func::from_wrapped(store, ty, Rc::new(callable)) Func::from_wrapped(store, ty, Rc::new(callable))
} }
} }
@@ -435,8 +435,10 @@ impl Memory {
} }
} }
// Marked unsafe due to posibility that wasmtime can resize internal memory /// Returns a mutable slice the current memory.
// from other threads. /// # Safety
/// Marked unsafe due to posibility that wasmtime can resize internal memory
/// from other threads.
pub unsafe fn data(&self) -> &mut [u8] { pub unsafe fn data(&self) -> &mut [u8] {
let definition = &*self.wasmtime_memory_definition(); let definition = &*self.wasmtime_memory_definition();
slice::from_raw_parts_mut(definition.base, definition.current_length) slice::from_raw_parts_mut(definition.base, definition.current_length)

View File

@@ -15,7 +15,7 @@ fn into_memory_type(mt: wasmparser::MemoryType) -> MemoryType {
MemoryType::new(Limits::new(mt.limits.initial, mt.limits.maximum)) MemoryType::new(Limits::new(mt.limits.initial, mt.limits.maximum))
} }
fn into_global_type(gt: &wasmparser::GlobalType) -> GlobalType { fn into_global_type(gt: wasmparser::GlobalType) -> GlobalType {
let mutability = if gt.mutable { let mutability = if gt.mutable {
Mutability::Var Mutability::Var
} else { } else {
@@ -24,6 +24,8 @@ fn into_global_type(gt: &wasmparser::GlobalType) -> GlobalType {
GlobalType::new(into_valtype(&gt.content_type), mutability) GlobalType::new(into_valtype(&gt.content_type), mutability)
} }
// `into_valtype` is used for `map` which requires `&T`.
#[allow(clippy::trivially_copy_pass_by_ref)]
fn into_valtype(ty: &wasmparser::Type) -> ValType { fn into_valtype(ty: &wasmparser::Type) -> ValType {
use wasmparser::Type::*; use wasmparser::Type::*;
match ty { match ty {
@@ -91,7 +93,7 @@ fn read_imports_and_exports(binary: &[u8]) -> Result<(Box<[ImportType]>, Box<[Ex
let section = section.get_global_section_reader()?; let section = section.get_global_section_reader()?;
globals.reserve_exact(section.get_count() as usize); globals.reserve_exact(section.get_count() as usize);
for entry in section { for entry in section {
globals.push(into_global_type(&entry?.ty)); globals.push(into_global_type(entry?.ty));
} }
} }
SectionCode::Table => { SectionCode::Table => {
@@ -123,7 +125,7 @@ fn read_imports_and_exports(binary: &[u8]) -> Result<(Box<[ImportType]>, Box<[Ex
ExternType::Memory(memory) ExternType::Memory(memory)
} }
ImportSectionEntryType::Global(gt) => { ImportSectionEntryType::Global(gt) => {
let global = into_global_type(&gt); let global = into_global_type(gt);
globals.push(global.clone()); globals.push(global.clone());
ExternType::Global(global) ExternType::Global(global)
} }

View File

@@ -31,16 +31,14 @@ pub(crate) fn create_handle(
// Compute indices into the shared signature table. // Compute indices into the shared signature table.
let signatures = signature_registry let signatures = signature_registry
.and_then(|mut signature_registry| { .map(|mut signature_registry| {
Some( module
module .signatures
.signatures .values()
.values() .map(|sig| signature_registry.register_wasmtime_signature(sig))
.map(|sig| signature_registry.register_wasmtime_signature(sig)) .collect::<PrimaryMap<_, _>>()
.collect::<PrimaryMap<_, _>>(),
)
}) })
.unwrap_or_else(|| PrimaryMap::new()); .unwrap_or_else(PrimaryMap::new);
Ok(InstanceHandle::new( Ok(InstanceHandle::new(
Rc::new(module), Rc::new(module),

View File

@@ -89,9 +89,9 @@ unsafe extern "C" fn stub_fn(vmctx: *mut VMContext, call_id: u32, values_vec: *m
match func.call(&args, &mut returns) { match func.call(&args, &mut returns) {
Ok(()) => { Ok(()) => {
for i in 0..returns_len { for (i, r#return) in returns.iter_mut().enumerate() {
// TODO check signature.returns[i].value_type ? // TODO check signature.returns[i].value_type ?
returns[i].write_value_to(values_vec.add(i)); r#return.write_value_to(values_vec.add(i));
} }
0 0
} }
@@ -172,7 +172,7 @@ fn make_trampoline(
let callee_args = vec![vmctx_ptr_val, call_id_val, values_vec_ptr_val]; let callee_args = vec![vmctx_ptr_val, call_id_val, values_vec_ptr_val];
let new_sig = builder.import_signature(stub_sig.clone()); let new_sig = builder.import_signature(stub_sig);
let callee_value = builder let callee_value = builder
.ins() .ins()

View File

@@ -547,7 +547,7 @@ impl Callable for wasm_func_callback_t {
let mut out_results = vec![wasm_val_t::default(); results.len()]; let mut out_results = vec![wasm_val_t::default(); results.len()];
let func = self.expect("wasm_func_callback_t fn"); let func = self.expect("wasm_func_callback_t fn");
let out = unsafe { func(params.as_ptr(), out_results.as_mut_ptr()) }; let out = unsafe { func(params.as_ptr(), out_results.as_mut_ptr()) };
if out != ptr::null_mut() { if !out.is_null() {
let trap: Box<wasm_trap_t> = unsafe { Box::from_raw(out) }; let trap: Box<wasm_trap_t> = unsafe { Box::from_raw(out) };
return Err((*trap).into()); return Err((*trap).into());
} }
@@ -579,7 +579,7 @@ impl Callable for CallbackWithEnv {
let mut out_results = vec![wasm_val_t::default(); results.len()]; let mut out_results = vec![wasm_val_t::default(); results.len()];
let func = self.callback.expect("wasm_func_callback_with_env_t fn"); let func = self.callback.expect("wasm_func_callback_with_env_t fn");
let out = unsafe { func(self.env, params.as_ptr(), out_results.as_mut_ptr()) }; let out = unsafe { func(self.env, params.as_ptr(), out_results.as_mut_ptr()) };
if out != ptr::null_mut() { if !out.is_null() {
let trap: Box<wasm_trap_t> = unsafe { Box::from_raw(out) }; let trap: Box<wasm_trap_t> = unsafe { Box::from_raw(out) };
return Err((*trap).into()); return Err((*trap).into());
} }
@@ -827,7 +827,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn wasm_val_copy(out: *mut wasm_val_t, source: *const wasm_val_t) { pub unsafe extern "C" fn wasm_val_copy(out: *mut wasm_val_t, source: *const wasm_val_t) {
*out = match into_valtype((*source).kind) { *out = match into_valtype((*source).kind) {
ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 => (*source).clone(), ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 => *source,
_ => unimplemented!("wasm_val_copy arg"), _ => unimplemented!("wasm_val_copy arg"),
}; };
} }

View File

@@ -29,7 +29,7 @@ impl SymbolResolver for FunctionRelocResolver {
pub fn emit_debugsections( pub fn emit_debugsections(
obj: &mut Artifact, obj: &mut Artifact,
vmctx_info: &ModuleVmctxInfo, vmctx_info: &ModuleVmctxInfo,
target_config: &TargetFrontendConfig, target_config: TargetFrontendConfig,
debuginfo_data: &DebugInfoData, debuginfo_data: &DebugInfoData,
at: &ModuleAddressMap, at: &ModuleAddressMap,
ranges: &ValueLabelsRanges, ranges: &ValueLabelsRanges,
@@ -53,7 +53,7 @@ impl<'a> SymbolResolver for ImageRelocResolver<'a> {
pub fn emit_debugsections_image( pub fn emit_debugsections_image(
triple: Triple, triple: Triple,
target_config: &TargetFrontendConfig, target_config: TargetFrontendConfig,
debuginfo_data: &DebugInfoData, debuginfo_data: &DebugInfoData,
vmctx_info: &ModuleVmctxInfo, vmctx_info: &ModuleVmctxInfo,
at: &ModuleAddressMap, at: &ModuleAddressMap,

View File

@@ -155,11 +155,8 @@ fn build_function_lookup(
active_ranges.push(range_index); active_ranges.push(range_index);
continue; continue;
} }
if last_wasm_pos.is_some() { if let Some(position) = last_wasm_pos {
index.insert( index.insert(position, active_ranges.clone().into_boxed_slice());
last_wasm_pos.unwrap(),
active_ranges.clone().into_boxed_slice(),
);
} }
active_ranges.retain(|r| ranges[*r].wasm_end.cmp(&wasm_start) != std::cmp::Ordering::Less); active_ranges.retain(|r| ranges[*r].wasm_end.cmp(&wasm_start) != std::cmp::Ordering::Less);
active_ranges.push(range_index); active_ranges.push(range_index);

View File

@@ -201,8 +201,8 @@ where
} }
found_expr found_expr
}; };
if found_single_expr.is_some() { if let Some(expr) = found_single_expr {
write::AttributeValue::Exprloc(found_single_expr.unwrap()) write::AttributeValue::Exprloc(expr)
} else if is_exprloc_to_loclist_allowed(attr.name()) { } else if is_exprloc_to_loclist_allowed(attr.name()) {
// Converting exprloc to loclist. // Converting exprloc to loclist.
let mut locs = Vec::new(); let mut locs = Vec::new();

View File

@@ -323,7 +323,7 @@ where
assert_eq!(ty, 0); assert_eq!(ty, 0);
let index = pc.read_sleb128()?; let index = pc.read_sleb128()?;
pc.read_u8()?; // consume 159 pc.read_u8()?; // consume 159
if code_chunk.len() > 0 { if !code_chunk.is_empty() {
parts.push(CompiledExpressionPart::Code(code_chunk)); parts.push(CompiledExpressionPart::Code(code_chunk));
code_chunk = Vec::new(); code_chunk = Vec::new();
} }
@@ -338,7 +338,7 @@ where
need_deref = false; need_deref = false;
} }
Operation::Deref { .. } => { Operation::Deref { .. } => {
if code_chunk.len() > 0 { if !code_chunk.is_empty() {
parts.push(CompiledExpressionPart::Code(code_chunk)); parts.push(CompiledExpressionPart::Code(code_chunk));
code_chunk = Vec::new(); code_chunk = Vec::new();
} }
@@ -353,14 +353,14 @@ where
} }
} }
if code_chunk.len() > 0 { if !code_chunk.is_empty() {
parts.push(CompiledExpressionPart::Code(code_chunk)); parts.push(CompiledExpressionPart::Code(code_chunk));
} }
if base_len > 0 && base_len + 1 < parts.len() { if base_len > 0 && base_len + 1 < parts.len() {
// see if we can glue two code chunks // see if we can glue two code chunks
if let [CompiledExpressionPart::Code(cc1), CompiledExpressionPart::Code(cc2)] = if let [CompiledExpressionPart::Code(cc1), CompiledExpressionPart::Code(cc2)] =
&parts[base_len..base_len + 1] &parts[base_len..=base_len]
{ {
let mut combined = cc1.clone(); let mut combined = cc1.clone();
combined.extend_from_slice(cc2); combined.extend_from_slice(cc2);

View File

@@ -45,7 +45,7 @@ where
} }
pub fn transform_dwarf( pub fn transform_dwarf(
target_config: &TargetFrontendConfig, target_config: TargetFrontendConfig,
di: &DebugInfoData, di: &DebugInfoData,
at: &ModuleAddressMap, at: &ModuleAddressMap,
vmctx_info: &ModuleVmctxInfo, vmctx_info: &ModuleVmctxInfo,

View File

@@ -67,10 +67,10 @@ impl RangeInfoBuilder {
result.push((range.begin, range.end)); result.push((range.begin, range.end));
} }
Ok(if result.len() > 0 { Ok(if result.is_empty() {
RangeInfoBuilder::Ranges(result)
} else {
RangeInfoBuilder::Undefined RangeInfoBuilder::Undefined
} else {
RangeInfoBuilder::Ranges(result)
}) })
} }

View File

@@ -51,37 +51,34 @@ where
R: Reader, R: Reader,
{ {
// FIXME remove recursion. // FIXME remove recursion.
match type_entry.attr_value(gimli::DW_AT_type)? { if let Some(AttributeValue::UnitRef(ref offset)) = type_entry.attr_value(gimli::DW_AT_type)? {
Some(AttributeValue::UnitRef(ref offset)) => { let mut entries = unit.entries_at_offset(*offset)?;
let mut entries = unit.entries_at_offset(*offset)?; entries.next_entry()?;
entries.next_entry()?; if let Some(die) = entries.current() {
if let Some(die) = entries.current() { if let Some(AttributeValue::DebugStrRef(str_offset)) =
if let Some(AttributeValue::DebugStrRef(str_offset)) = die.attr_value(gimli::DW_AT_name)?
die.attr_value(gimli::DW_AT_name)? {
{ return Ok(String::from(
return Ok(String::from( context.debug_str.get_str(str_offset)?.to_string()?,
context.debug_str.get_str(str_offset)?.to_string()?, ));
)); }
match die.tag() {
gimli::DW_TAG_const_type => {
return Ok(format!("const {}", get_base_type_name(die, unit, context)?));
} }
match die.tag() { gimli::DW_TAG_pointer_type => {
gimli::DW_TAG_const_type => { return Ok(format!("{}*", get_base_type_name(die, unit, context)?));
return Ok(format!("const {}", get_base_type_name(die, unit, context)?));
}
gimli::DW_TAG_pointer_type => {
return Ok(format!("{}*", get_base_type_name(die, unit, context)?));
}
gimli::DW_TAG_reference_type => {
return Ok(format!("{}&", get_base_type_name(die, unit, context)?));
}
gimli::DW_TAG_array_type => {
return Ok(format!("{}[]", get_base_type_name(die, unit, context)?));
}
_ => (),
} }
gimli::DW_TAG_reference_type => {
return Ok(format!("{}&", get_base_type_name(die, unit, context)?));
}
gimli::DW_TAG_array_type => {
return Ok(format!("{}[]", get_base_type_name(die, unit, context)?));
}
_ => (),
} }
} }
_ => (), }
};
Ok(String::from("??")) Ok(String::from("??"))
} }
@@ -121,11 +118,8 @@ where
gimli::DW_AT_type, gimli::DW_AT_type,
write::AttributeValue::ThisUnitEntryRef(wp_die_id), write::AttributeValue::ThisUnitEntryRef(wp_die_id),
); );
match entry.attr_value(gimli::DW_AT_type)? { if let Some(AttributeValue::UnitRef(ref offset)) = entry.attr_value(gimli::DW_AT_type)? {
Some(AttributeValue::UnitRef(ref offset)) => { pending_die_refs.push((p_die_id, gimli::DW_AT_type, *offset))
pending_die_refs.push((p_die_id, gimli::DW_AT_type, *offset))
}
_ => (),
} }
let m_die_id = comp_unit.add(die_id, gimli::DW_TAG_member); let m_die_id = comp_unit.add(die_id, gimli::DW_TAG_member);

View File

@@ -56,6 +56,7 @@ struct ModuleCacheEntryInner<'config, 'worker> {
worker: &'worker Worker, worker: &'worker Worker,
} }
/// Cached compilation data of a Wasm module.
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct ModuleCacheData { pub struct ModuleCacheData {
compilation: Compilation, compilation: Compilation,
@@ -66,7 +67,8 @@ pub struct ModuleCacheData {
traps: Traps, traps: Traps,
} }
type ModuleCacheDataTupleType = ( /// A type alias over the module cache data as a tuple.
pub type ModuleCacheDataTupleType = (
Compilation, Compilation,
Relocations, Relocations,
ModuleAddressMap, ModuleAddressMap,
@@ -102,7 +104,7 @@ impl<'config, 'worker> ModuleCacheEntry<'config, 'worker> {
} }
#[cfg(test)] #[cfg(test)]
fn from_inner<'data>(inner: ModuleCacheEntryInner<'config, 'worker>) -> Self { fn from_inner(inner: ModuleCacheEntryInner<'config, 'worker>) -> Self {
Self(Some(inner)) Self(Some(inner))
} }
@@ -119,10 +121,9 @@ impl<'config, 'worker> ModuleCacheEntry<'config, 'worker> {
pub fn update_data(&self, data: &ModuleCacheData) { pub fn update_data(&self, data: &ModuleCacheData) {
if let Some(inner) = &self.0 { if let Some(inner) = &self.0 {
inner.update_data(data).map(|val| { if inner.update_data(data).is_some() {
inner.worker.on_cache_update_async(&inner.mod_cache_path); // call on success inner.worker.on_cache_update_async(&inner.mod_cache_path); // call on success
val }
});
} }
} }
} }
@@ -236,7 +237,7 @@ impl ModuleCacheData {
} }
} }
pub fn to_tuple(self) -> ModuleCacheDataTupleType { pub fn into_tuple(self) -> ModuleCacheDataTupleType {
( (
self.compilation, self.compilation,
self.relocations, self.relocations,

View File

@@ -148,10 +148,10 @@ pub fn create_new_config<P: AsRef<Path> + Debug>(
)?; )?;
if config_file.exists() { if config_file.exists() {
Err(format!( return Err(format!(
"Specified config file already exists! Path: {}", "Specified config file already exists! Path: {}",
config_file.display() config_file.display()
))?; ));
} }
let parent_dir = config_file let parent_dir = config_file

View File

@@ -120,26 +120,28 @@ impl Worker {
#[inline] #[inline]
fn send_cache_event(&self, event: CacheEvent) { fn send_cache_event(&self, event: CacheEvent) {
#[cfg(test)] let sent_event = self.sender.try_send(event.clone());
let mut stats = self
.stats
.0
.lock()
.expect("Failed to acquire worker stats lock");
match self.sender.try_send(event.clone()) {
Ok(()) => {
#[cfg(test)]
let _ = stats.sent += 1;
}
Err(err) => {
info!(
"Failed to send asynchronously message to worker thread, \
event: {:?}, error: {}",
event, err
);
#[cfg(test)] if let Err(ref err) = sent_event {
let _ = stats.dropped += 1; info!(
"Failed to send asynchronously message to worker thread, \
event: {:?}, error: {}",
event, err
);
}
#[cfg(test)]
{
let mut stats = self
.stats
.0
.lock()
.expect("Failed to acquire worker stats lock");
if sent_event.is_ok() {
stats.sent += 1;
} else {
stats.dropped += 1;
} }
} }
} }
@@ -194,6 +196,18 @@ enum CacheEntry {
}, },
} }
macro_rules! unwrap_or_warn {
($result:expr, $cont:stmt, $err_msg:expr, $path:expr) => {
match $result {
Ok(val) => val,
Err(err) => {
warn!("{}, path: {}, msg: {}", $err_msg, $path.display(), err);
$cont
}
}
};
}
impl WorkerThread { impl WorkerThread {
fn run(self, init_file_per_thread_logger: Option<&'static str>) { fn run(self, init_file_per_thread_logger: Option<&'static str>) {
#[cfg(not(test))] // We want to test the worker without relying on init() being called #[cfg(not(test))] // We want to test the worker without relying on init() being called
@@ -321,91 +335,85 @@ impl WorkerThread {
// recompress, write to other file, rename (it's atomic file content exchange) // recompress, write to other file, rename (it's atomic file content exchange)
// and update the stats file // and update the stats file
fs::read(&path) let compressed_cache_bytes = unwrap_or_warn!(
.map_err(|err| { fs::read(&path),
warn!( return,
"Failed to read old cache file, path: {}, err: {}", "Failed to read old cache file",
path.display(), path
err );
)
})
.ok()
.and_then(|compressed_cache_bytes| {
zstd::decode_all(&compressed_cache_bytes[..])
.map_err(|err| warn!("Failed to decompress cached code: {}", err))
.ok()
})
.and_then(|cache_bytes| {
zstd::encode_all(&cache_bytes[..], opt_compr_lvl)
.map_err(|err| warn!("Failed to compress cached code: {}", err))
.ok()
})
.and_then(|recompressed_cache_bytes| {
fs::write(&lock_path, &recompressed_cache_bytes)
.map_err(|err| {
warn!(
"Failed to write recompressed cache, path: {}, err: {}",
lock_path.display(),
err
)
})
.ok()
})
.and_then(|()| {
fs::rename(&lock_path, &path)
.map_err(|err| {
warn!(
"Failed to rename recompressed cache, path from: {}, path to: {}, err: {}",
lock_path.display(),
path.display(),
err
);
if let Err(err) = fs::remove_file(&lock_path) {
warn!(
"Failed to clean up (remove) recompressed cache, path {}, err: {}",
lock_path.display(),
err
);
}
})
.ok()
})
.map(|()| {
// update stats file (reload it! recompression can take some time)
if let Some(mut new_stats) = read_stats_file(stats_path.as_ref()) {
if new_stats.compression_level >= opt_compr_lvl {
// Rare race:
// two instances with different opt_compr_lvl: we don't know in which order they updated
// the cache file and the stats file (they are not updated together atomically)
// Possible solution is to use directories per cache entry, but it complicates the system
// and is not worth it.
debug!(
"DETECTED task did more than once (or race with new file): \
recompression of {}. Note: if optimized compression level setting \
has changed in the meantine, the stats file might contain \
inconsistent compression level due to race.",
path.display()
);
} else {
new_stats.compression_level = opt_compr_lvl;
let _ = write_stats_file(stats_path.as_ref(), &new_stats);
}
if new_stats.usages < stats.usages { let cache_bytes = unwrap_or_warn!(
debug!( zstd::decode_all(&compressed_cache_bytes[..]),
"DETECTED lower usage count (new file or race with counter \ return,
increasing): file {}", "Failed to decompress cached code",
path.display() path
); );
}
} else { let recompressed_cache_bytes = unwrap_or_warn!(
debug!( zstd::encode_all(&cache_bytes[..], opt_compr_lvl),
"Can't read stats file again to update compression level (it might got \ return,
cleaned up): file {}", "Failed to compress cached code",
stats_path.display() path
);
unwrap_or_warn!(
fs::write(&lock_path, &recompressed_cache_bytes),
return,
"Failed to write recompressed cache",
lock_path
);
unwrap_or_warn!(
fs::rename(&lock_path, &path),
{
if let Err(error) = fs::remove_file(&lock_path) {
warn!(
"Failed to clean up (remove) recompressed cache, path {}, err: {}",
lock_path.display(),
error
); );
} }
});
return;
},
"Failed to rename recompressed cache",
lock_path
);
// update stats file (reload it! recompression can take some time)
if let Some(mut new_stats) = read_stats_file(stats_path.as_ref()) {
if new_stats.compression_level >= opt_compr_lvl {
// Rare race:
// two instances with different opt_compr_lvl: we don't know in which order they updated
// the cache file and the stats file (they are not updated together atomically)
// Possible solution is to use directories per cache entry, but it complicates the system
// and is not worth it.
debug!(
"DETECTED task did more than once (or race with new file): \
recompression of {}. Note: if optimized compression level setting \
has changed in the meantine, the stats file might contain \
inconsistent compression level due to race.",
path.display()
);
} else {
new_stats.compression_level = opt_compr_lvl;
let _ = write_stats_file(stats_path.as_ref(), &new_stats);
}
if new_stats.usages < stats.usages {
debug!(
"DETECTED lower usage count (new file or race with counter \
increasing): file {}",
path.display()
);
}
} else {
debug!(
"Can't read stats file again to update compression level (it might got \
cleaned up): file {}",
stats_path.display()
);
}
trace!("Task finished: recompress file: {}", path.display()); trace!("Task finished: recompress file: {}", path.display());
} }
@@ -508,10 +516,10 @@ impl WorkerThread {
}; };
total_size += size; total_size += size;
if start_delete_idx_if_deleting_recognized_items.is_none() { if start_delete_idx_if_deleting_recognized_items.is_none()
if total_size > tsl_if_deleting || (idx + 1) as u64 > fcl_if_deleting { && (total_size > tsl_if_deleting || (idx + 1) as u64 > fcl_if_deleting)
start_delete_idx_if_deleting_recognized_items = Some(idx); {
} start_delete_idx_if_deleting_recognized_items = Some(idx);
} }
if total_size > total_size_limit || (idx + 1) as u64 > file_count_limit { if total_size > total_size_limit || (idx + 1) as u64 > file_count_limit {
@@ -554,26 +562,6 @@ impl WorkerThread {
level: u8, level: u8,
cache_config: &CacheConfig, cache_config: &CacheConfig,
) { ) {
macro_rules! unwrap_or {
($result:expr, $cont:stmt, $err_msg:expr) => {
unwrap_or!($result, $cont, $err_msg, dir_path)
};
($result:expr, $cont:stmt, $err_msg:expr, $path:expr) => {
match $result {
Ok(val) => val,
Err(err) => {
warn!(
"{}, level: {}, path: {}, msg: {}",
$err_msg,
level,
$path.display(),
err
);
$cont
}
}
};
}
macro_rules! add_unrecognized { macro_rules! add_unrecognized {
(file: $path:expr) => { (file: $path:expr) => {
add_unrecognized!(false, $path) add_unrecognized!(false, $path)
@@ -591,10 +579,24 @@ impl WorkerThread {
macro_rules! add_unrecognized_and { macro_rules! add_unrecognized_and {
([ $( $ty:ident: $path:expr ),* ], $cont:stmt) => {{ ([ $( $ty:ident: $path:expr ),* ], $cont:stmt) => {{
$( add_unrecognized!($ty: $path); )* $( add_unrecognized!($ty: $path); )*
$cont $cont
}}; }};
} }
macro_rules! unwrap_or {
($result:expr, $cont:stmt, $err_msg:expr) => {
unwrap_or!($result, $cont, $err_msg, dir_path)
};
($result:expr, $cont:stmt, $err_msg:expr, $path:expr) => {
unwrap_or_warn!(
$result,
$cont,
format!("{}, level: {}", $err_msg, level),
$path
)
};
}
// If we fail to list a directory, something bad is happening anyway // If we fail to list a directory, something bad is happening anyway
// (something touches our cache or we have disk failure) // (something touches our cache or we have disk failure)
// Try to delete it, so we can stay within soft limits of the cache size. // Try to delete it, so we can stay within soft limits of the cache size.
@@ -619,43 +621,41 @@ impl WorkerThread {
match (level, path.is_dir()) { match (level, path.is_dir()) {
(0..=1, true) => enter_dir(vec, &path, level + 1, cache_config), (0..=1, true) => enter_dir(vec, &path, level + 1, cache_config),
(0..=1, false) => { (0..=1, false) => {
if level == 0 && path.file_stem() == Some(OsStr::new(".cleanup")) { if level == 0
if path.extension().is_some() { && path.file_stem() == Some(OsStr::new(".cleanup"))
&& path.extension().is_some()
// assume it's cleanup lock // assume it's cleanup lock
if !is_fs_lock_expired( && !is_fs_lock_expired(
Some(&entry), Some(&entry),
&path, &path,
cache_config.cleanup_interval(), cache_config.cleanup_interval(),
cache_config.allowed_clock_drift_for_files_from_future(), cache_config.allowed_clock_drift_for_files_from_future(),
) { )
continue; // skip active lock {
} continue; // skip active lock
}
} }
add_unrecognized!(file: path); add_unrecognized!(file: path);
} }
(2, false) => { (2, false) => {
let ext = path.extension(); match path.extension().and_then(OsStr::to_str) {
if ext.is_none() || ext == Some(OsStr::new("stats")) {
// mod or stats file // mod or stats file
cache_files.insert(path, entry); None | Some("stats") => {
} else { cache_files.insert(path, entry);
let recognized = if let Some(ext_str) = ext.unwrap().to_str() { }
Some(ext) => {
// check if valid lock // check if valid lock
ext_str.starts_with("wip-") let recognized = ext.starts_with("wip-")
&& !is_fs_lock_expired( && !is_fs_lock_expired(
Some(&entry), Some(&entry),
&path, &path,
cache_config.optimizing_compression_task_timeout(), cache_config.optimizing_compression_task_timeout(),
cache_config.allowed_clock_drift_for_files_from_future(), cache_config.allowed_clock_drift_for_files_from_future(),
) );
} else {
// if it's None, i.e. not valid UTF-8 string, then that's not our lock for sure
false
};
if !recognized { if !recognized {
add_unrecognized!(file: path); add_unrecognized!(file: path);
}
} }
} }
} }

View File

@@ -1,7 +1,7 @@
//! A `Compilation` contains the compiled function bodies for a WebAssembly //! A `Compilation` contains the compiled function bodies for a WebAssembly
//! module. //! module.
use crate::address_map::{ModuleAddressMap, ValueLabelsRanges}; use crate::cache::ModuleCacheDataTupleType;
use crate::module; use crate::module;
use crate::module_environ::FunctionBodyData; use crate::module_environ::FunctionBodyData;
use cranelift_codegen::{binemit, ir, isa}; use cranelift_codegen::{binemit, ir, isa};
@@ -66,6 +66,11 @@ impl Compilation {
self.functions.len() self.functions.len()
} }
/// Returns whether there are no functions defined.
pub fn is_empty(&self) -> bool {
self.functions.is_empty()
}
/// Gets functions jump table offsets. /// Gets functions jump table offsets.
pub fn get_jt_offsets(&self) -> PrimaryMap<DefinedFuncIndex, ir::JumpTableOffsets> { pub fn get_jt_offsets(&self) -> PrimaryMap<DefinedFuncIndex, ir::JumpTableOffsets> {
self.functions self.functions
@@ -172,15 +177,5 @@ pub trait Compiler {
function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>, function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
isa: &dyn isa::TargetIsa, isa: &dyn isa::TargetIsa,
generate_debug_info: bool, generate_debug_info: bool,
) -> Result< ) -> Result<ModuleCacheDataTupleType, CompileError>;
(
Compilation,
Relocations,
ModuleAddressMap,
ValueLabelsRanges,
PrimaryMap<DefinedFuncIndex, ir::StackSlots>,
Traps,
),
CompileError,
>;
} }

View File

@@ -1,12 +1,9 @@
//! Support for compiling with Cranelift. //! Support for compiling with Cranelift.
use crate::address_map::{ use crate::address_map::{FunctionAddressMap, InstructionAddressMap};
FunctionAddressMap, InstructionAddressMap, ModuleAddressMap, ValueLabelsRanges, use crate::cache::{ModuleCacheData, ModuleCacheDataTupleType, ModuleCacheEntry};
};
use crate::cache::{ModuleCacheData, ModuleCacheEntry};
use crate::compilation::{ use crate::compilation::{
Compilation, CompileError, CompiledFunction, Relocation, RelocationTarget, Relocations, Compilation, CompileError, CompiledFunction, Relocation, RelocationTarget, TrapInformation,
TrapInformation, Traps,
}; };
use crate::func_environ::{ use crate::func_environ::{
get_func_name, get_imported_memory32_grow_name, get_imported_memory32_size_name, get_func_name, get_imported_memory32_grow_name, get_imported_memory32_size_name,
@@ -14,12 +11,9 @@ use crate::func_environ::{
}; };
use crate::module::Module; use crate::module::Module;
use crate::module_environ::FunctionBodyData; use crate::module_environ::FunctionBodyData;
use cranelift_codegen::binemit; use cranelift_codegen::ir::{self, ExternalName};
use cranelift_codegen::ir;
use cranelift_codegen::ir::ExternalName;
use cranelift_codegen::isa;
use cranelift_codegen::print_errors::pretty_error; use cranelift_codegen::print_errors::pretty_error;
use cranelift_codegen::Context; use cranelift_codegen::{binemit, isa, Context};
use cranelift_entity::PrimaryMap; use cranelift_entity::PrimaryMap;
use cranelift_wasm::{DefinedFuncIndex, FuncIndex, FuncTranslator, ModuleTranslationState}; use cranelift_wasm::{DefinedFuncIndex, FuncIndex, FuncTranslator, ModuleTranslationState};
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
@@ -181,17 +175,7 @@ impl crate::compilation::Compiler for Cranelift {
function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>, function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
isa: &dyn isa::TargetIsa, isa: &dyn isa::TargetIsa,
generate_debug_info: bool, generate_debug_info: bool,
) -> Result< ) -> Result<ModuleCacheDataTupleType, CompileError> {
(
Compilation,
Relocations,
ModuleAddressMap,
ValueLabelsRanges,
PrimaryMap<DefinedFuncIndex, ir::StackSlots>,
Traps,
),
CompileError,
> {
let cache_entry = ModuleCacheEntry::new( let cache_entry = ModuleCacheEntry::new(
module, module,
&function_body_inputs, &function_body_inputs,
@@ -214,82 +198,75 @@ impl crate::compilation::Compiler for Cranelift {
.into_iter() .into_iter()
.collect::<Vec<(DefinedFuncIndex, &FunctionBodyData<'data>)>>() .collect::<Vec<(DefinedFuncIndex, &FunctionBodyData<'data>)>>()
.par_iter() .par_iter()
.map_init( .map_init(FuncTranslator::new, |func_translator, (i, input)| {
|| FuncTranslator::new(), let func_index = module.func_index(*i);
|func_translator, (i, input)| { let mut context = Context::new();
let func_index = module.func_index(*i); context.func.name = get_func_name(func_index);
let mut context = Context::new(); context.func.signature =
context.func.name = get_func_name(func_index); module.signatures[module.functions[func_index]].clone();
context.func.signature = if generate_debug_info {
module.signatures[module.functions[func_index]].clone(); context.func.collect_debug_info();
if generate_debug_info { }
context.func.collect_debug_info();
}
func_translator.translate( func_translator.translate(
module_translation, module_translation,
input.data, input.data,
input.module_offset, input.module_offset,
&mut context.func, &mut context.func,
&mut FuncEnvironment::new(isa.frontend_config(), module), &mut FuncEnvironment::new(isa.frontend_config(), module),
)?; )?;
let mut code_buf: Vec<u8> = Vec::new(); let mut code_buf: Vec<u8> = Vec::new();
let mut unwind_info = Vec::new(); let mut unwind_info = Vec::new();
let mut reloc_sink = RelocSink::new(func_index); let mut reloc_sink = RelocSink::new(func_index);
let mut trap_sink = TrapSink::new(); let mut trap_sink = TrapSink::new();
let mut stackmap_sink = binemit::NullStackmapSink {}; let mut stackmap_sink = binemit::NullStackmapSink {};
context context
.compile_and_emit( .compile_and_emit(
isa, isa,
&mut code_buf, &mut code_buf,
&mut reloc_sink, &mut reloc_sink,
&mut trap_sink, &mut trap_sink,
&mut stackmap_sink, &mut stackmap_sink,
) )
.map_err(|error| { .map_err(|error| {
CompileError::Codegen(pretty_error(&context.func, Some(isa), error))
})?;
context.emit_unwind_info(isa, &mut unwind_info);
let address_transform = if generate_debug_info {
let body_len = code_buf.len();
Some(get_function_address_map(&context, input, body_len, isa))
} else {
None
};
let ranges = if generate_debug_info {
let ranges =
context.build_value_labels_ranges(isa).map_err(|error| {
CompileError::Codegen(pretty_error( CompileError::Codegen(pretty_error(
&context.func, &context.func,
Some(isa), Some(isa),
error, error,
)) ))
})?; })?;
Some(ranges)
} else {
None
};
context.emit_unwind_info(isa, &mut unwind_info); Ok((
code_buf,
let address_transform = if generate_debug_info { context.func.jt_offsets,
let body_len = code_buf.len(); reloc_sink.func_relocs,
Some(get_function_address_map(&context, input, body_len, isa)) address_transform,
} else { ranges,
None context.func.stack_slots,
}; trap_sink.traps,
unwind_info,
let ranges = if generate_debug_info { ))
let ranges = })
context.build_value_labels_ranges(isa).map_err(|error| {
CompileError::Codegen(pretty_error(
&context.func,
Some(isa),
error,
))
})?;
Some(ranges)
} else {
None
};
Ok((
code_buf,
context.func.jt_offsets,
reloc_sink.func_relocs,
address_transform,
ranges,
context.func.stack_slots,
trap_sink.traps,
unwind_info,
))
},
)
.collect::<Result<Vec<_>, CompileError>>()? .collect::<Result<Vec<_>, CompileError>>()?
.into_iter() .into_iter()
.for_each( .for_each(
@@ -333,6 +310,6 @@ impl crate::compilation::Compiler for Cranelift {
} }
}; };
Ok(data.to_tuple()) Ok(data.into_tuple())
} }
} }

View File

@@ -450,9 +450,9 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
// allocated up front and never moved. // allocated up front and never moved.
let (offset_guard_size, heap_style, readonly_base) = match self.module.memory_plans[index] { let (offset_guard_size, heap_style, readonly_base) = match self.module.memory_plans[index] {
MemoryPlan { MemoryPlan {
memory: _,
style: MemoryStyle::Dynamic, style: MemoryStyle::Dynamic,
offset_guard_size, offset_guard_size,
memory: _,
} => { } => {
let heap_bound = func.create_global_value(ir::GlobalValueData::Load { let heap_bound = func.create_global_value(ir::GlobalValueData::Load {
base: ptr, base: ptr,
@@ -469,9 +469,9 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
) )
} }
MemoryPlan { MemoryPlan {
memory: _,
style: MemoryStyle::Static { bound }, style: MemoryStyle::Static { bound },
offset_guard_size, offset_guard_size,
memory: _,
} => ( } => (
Uimm64::new(offset_guard_size), Uimm64::new(offset_guard_size),
ir::HeapStyle::Static { ir::HeapStyle::Static {

View File

@@ -1,5 +1,6 @@
//! Support for compiling with Lightbeam. //! Support for compiling with Lightbeam.
use crate::cache::ModuleCacheDataTupleType;
use crate::compilation::{Compilation, CompileError, Relocations, Traps}; use crate::compilation::{Compilation, CompileError, Relocations, Traps};
use crate::func_environ::FuncEnvironment; use crate::func_environ::FuncEnvironment;
use crate::module::Module; use crate::module::Module;
@@ -24,17 +25,7 @@ impl crate::compilation::Compiler for Lightbeam {
isa: &dyn isa::TargetIsa, isa: &dyn isa::TargetIsa,
// TODO // TODO
generate_debug_info: bool, generate_debug_info: bool,
) -> Result< ) -> Result<ModuleCacheDataTupleType, CompileError> {
(
Compilation,
Relocations,
ModuleAddressMap,
ValueLabelsRanges,
PrimaryMap<DefinedFuncIndex, ir::StackSlots>,
Traps,
),
CompileError,
> {
if generate_debug_info { if generate_debug_info {
return Err(CompileError::DebugInfoNotSupported); return Err(CompileError::DebugInfoNotSupported);
} }

View File

@@ -17,10 +17,7 @@ fn cast_to_u32(sz: usize) -> u32 {
} }
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
fn cast_to_u32(sz: usize) -> u32 { fn cast_to_u32(sz: usize) -> u32 {
match u32::try_from(sz) { u32::try_from(sz).expect("overflow in cast from usize to u32")
Ok(x) => x,
Err(_) => panic!("overflow in cast from usize to u32"),
}
} }
/// Align an offset used in this module to a specific byte-width by rounding up /// Align an offset used in this module to a specific byte-width by rounding up

View File

@@ -77,7 +77,7 @@ impl CodeMemory {
.expect("failed to push current memory map"); .expect("failed to push current memory map");
for (m, t) in &mut self.mmaps[self.published..] { for (m, t) in &mut self.mmaps[self.published..] {
if m.len() != 0 { if !m.is_empty() {
unsafe { unsafe {
region::protect(m.as_mut_ptr(), m.len(), region::Protection::ReadExecute) region::protect(m.as_mut_ptr(), m.len(), region::Protection::ReadExecute)
} }
@@ -179,7 +179,7 @@ impl CodeMemory {
), ),
); );
if previous.0.len() > 0 { if !previous.0.is_empty() {
self.mmaps.push(previous); self.mmaps.push(previous);
} else { } else {
assert_eq!(previous.1.len(), 0); assert_eq!(previous.1.len(), 0);

View File

@@ -175,14 +175,14 @@ impl Compiler {
}; };
let bytes = emit_debugsections_image( let bytes = emit_debugsections_image(
self.isa.triple().clone(), self.isa.triple().clone(),
&target_config, target_config,
&debug_data, &debug_data,
&module_vmctx_info, &module_vmctx_info,
&address_transform, &address_transform,
&value_ranges, &value_ranges,
&funcs, &funcs,
) )
.map_err(|e| SetupError::DebugInfo(e))?; .map_err(SetupError::DebugInfo)?;
Some(bytes) Some(bytes)
} else { } else {
None None

View File

@@ -244,6 +244,6 @@ impl Context {
pub fn get_global_exports( pub fn get_global_exports(
&mut self, &mut self,
) -> Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>> { ) -> Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>> {
Rc::clone(&mut self.global_exports) Rc::clone(&self.global_exports)
} }
} }

View File

@@ -190,7 +190,7 @@ impl CompiledModule {
imports, imports,
data_initializers, data_initializers,
signatures, signatures,
dbg_jit_registration: dbg_jit_registration.map(|r| Rc::new(r)), dbg_jit_registration: dbg_jit_registration.map(Rc::new),
} }
} }
@@ -254,6 +254,7 @@ impl OwnedDataInitializer {
/// ///
/// This is equivalent to createing a `CompiledModule` and calling `instantiate()` on it, /// This is equivalent to createing a `CompiledModule` and calling `instantiate()` on it,
/// but avoids creating an intermediate copy of the data initializers. /// but avoids creating an intermediate copy of the data initializers.
#[allow(clippy::implicit_hasher)]
pub fn instantiate( pub fn instantiate(
compiler: &mut Compiler, compiler: &mut Compiler,
data: &[u8], data: &[u8],
@@ -270,7 +271,7 @@ pub fn instantiate(
raw.imports, raw.imports,
&*raw.data_initializers, &*raw.data_initializers,
raw.signatures, raw.signatures,
raw.dbg_jit_registration.map(|r| Rc::new(r)), raw.dbg_jit_registration.map(Rc::new),
Box::new(()), Box::new(()),
) )
.map_err(SetupError::Instantiate) .map_err(SetupError::Instantiate)

View File

@@ -129,16 +129,14 @@ pub fn link_module(
// Sanity-check: Ensure that the imported memory has at least // Sanity-check: Ensure that the imported memory has at least
// guard-page protections the importing module expects it to have. // guard-page protections the importing module expects it to have.
match (memory.style, &import_memory.style) { if let (
( MemoryStyle::Static { bound },
MemoryStyle::Static { bound }, MemoryStyle::Static {
MemoryStyle::Static { bound: import_bound,
bound: import_bound, },
}, ) = (memory.style, &import_memory.style)
) => { {
assert_ge!(bound, *import_bound); assert_ge!(bound, *import_bound);
}
_ => (),
} }
assert_ge!(memory.offset_guard_size, import_memory.offset_guard_size); assert_ge!(memory.offset_guard_size, import_memory.offset_guard_size);

View File

@@ -8,10 +8,7 @@
)] )]
#![warn(unused_import_braces)] #![warn(unused_import_braces)]
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
#![cfg_attr( #![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))]
feature = "cargo-clippy",
allow(clippy::new_without_default, clippy::new_without_default_derive)
)]
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
warn( warn(

View File

@@ -38,8 +38,8 @@ pub fn emit_module(
) -> Result<(), String> { ) -> Result<(), String> {
declare_functions(obj, module, relocations)?; declare_functions(obj, module, relocations)?;
for i in 0..data_initializers.len() { for (i, initializer) in data_initializers.iter().enumerate() {
declare_data_segment(obj, &data_initializers[i], i)?; declare_data_segment(obj, initializer, i)?;
} }
for i in 0..module.table_plans.len() { for i in 0..module.table_plans.len() {
@@ -48,8 +48,8 @@ pub fn emit_module(
emit_functions(obj, module, compilation, relocations)?; emit_functions(obj, module, compilation, relocations)?;
for i in 0..data_initializers.len() { for (i, initializer) in data_initializers.iter().enumerate() {
emit_data_segment(obj, &data_initializers[i], i)?; emit_data_segment(obj, initializer, i)?;
} }
for i in 0..module.table_plans.len() { for i in 0..module.table_plans.len() {

View File

@@ -396,9 +396,12 @@ impl Instance {
Some(self.lookup_by_declaration(&export)) Some(self.lookup_by_declaration(&export))
} }
/// Lookup an export with the given name. This takes an immutable reference, /// Lookup an export with the given name.
/// and the result is an `Export` that the type system doesn't prevent from ///
/// being used to mutate the instance, so this function is unsafe. /// # Safety
/// This takes an immutable reference, and the result is an `Export` that
/// the type system doesn't prevent from being used to mutate the instance,
/// so this function is unsafe.
pub unsafe fn lookup_immutable(&self, field: &str) -> Option<Export> { pub unsafe fn lookup_immutable(&self, field: &str) -> Option<Export> {
#[allow(clippy::cast_ref_to_mut)] #[allow(clippy::cast_ref_to_mut)]
let temporary_mut = &mut *(self as *const Self as *mut Self); let temporary_mut = &mut *(self as *const Self as *mut Self);
@@ -416,9 +419,12 @@ impl Instance {
) )
} }
/// Lookup an export with the given export declaration. This takes an immutable /// Lookup an export with the given export declaration.
/// reference, and the result is an `Export` that the type system doesn't prevent ///
/// from being used to mutate the instance, so this function is unsafe. /// # Safety
/// This takes an immutable reference, and the result is an `Export` that
/// the type system doesn't prevent from being used to mutate the instance,
/// so this function is unsafe.
pub unsafe fn lookup_immutable_by_declaration( pub unsafe fn lookup_immutable_by_declaration(
&self, &self,
export: &wasmtime_environ::Export, export: &wasmtime_environ::Export,
@@ -545,8 +551,9 @@ impl Instance {
/// Returns `None` if memory can't be grown by the specified amount /// Returns `None` if memory can't be grown by the specified amount
/// of pages. /// of pages.
/// ///
/// TODO: This and `imported_memory_size` are currently unsafe because /// # Safety
/// they dereference the memory import's pointers. /// This and `imported_memory_size` are currently unsafe because they
/// dereference the memory import's pointers.
pub(crate) unsafe fn imported_memory_grow( pub(crate) unsafe fn imported_memory_grow(
&mut self, &mut self,
memory_index: MemoryIndex, memory_index: MemoryIndex,
@@ -569,6 +576,10 @@ impl Instance {
} }
/// Returns the number of allocated wasm pages in an imported memory. /// Returns the number of allocated wasm pages in an imported memory.
///
/// # Safety
/// This and `imported_memory_grow` are currently unsafe because they
/// dereference the memory import's pointers.
pub(crate) unsafe fn imported_memory_size(&mut self, memory_index: MemoryIndex) -> u32 { pub(crate) unsafe fn imported_memory_size(&mut self, memory_index: MemoryIndex) -> u32 {
let import = self.imported_memory(memory_index); let import = self.imported_memory(memory_index);
let foreign_instance = (&mut *import.vmctx).instance(); let foreign_instance = (&mut *import.vmctx).instance();
@@ -785,6 +796,10 @@ impl InstanceHandle {
/// Create a new `InstanceHandle` pointing at the instance /// Create a new `InstanceHandle` pointing at the instance
/// pointed to by the given `VMContext` pointer. /// pointed to by the given `VMContext` pointer.
///
/// # Safety
/// This is unsafe because it doesn't work on just any `VMContext`, it must
/// be a `VMContext` allocated as part of an `Instance`.
pub unsafe fn from_vmctx(vmctx: *mut VMContext) -> Self { pub unsafe fn from_vmctx(vmctx: *mut VMContext) -> Self {
let instance = (&mut *vmctx).instance(); let instance = (&mut *vmctx).instance();
instance.refcount += 1; instance.refcount += 1;
@@ -826,9 +841,12 @@ impl InstanceHandle {
self.instance_mut().lookup(field) self.instance_mut().lookup(field)
} }
/// Lookup an export with the given name. This takes an immutable reference, /// Lookup an export with the given name.
/// and the result is an `Export` that the type system doesn't prevent from ///
/// being used to mutate the instance, so this function is unsafe. /// # Safety
/// This takes an immutable reference, and the result is an `Export` that
/// the type system doesn't prevent from being used to mutate the instance,
/// so this function is unsafe.
pub unsafe fn lookup_immutable(&self, field: &str) -> Option<Export> { pub unsafe fn lookup_immutable(&self, field: &str) -> Option<Export> {
self.instance().lookup_immutable(field) self.instance().lookup_immutable(field)
} }
@@ -838,9 +856,12 @@ impl InstanceHandle {
self.instance_mut().lookup_by_declaration(export) self.instance_mut().lookup_by_declaration(export)
} }
/// Lookup an export with the given export declaration. This takes an immutable /// Lookup an export with the given export declaration.
/// reference, and the result is an `Export` that the type system doesn't prevent ///
/// from being used to mutate the instance, so this function is unsafe. /// # Safety
/// This takes an immutable reference, and the result is an `Export` that
/// the type system doesn't prevent from being used to mutate the instance,
/// so this function is unsafe.
pub unsafe fn lookup_immutable_by_declaration( pub unsafe fn lookup_immutable_by_declaration(
&self, &self,
export: &wasmtime_environ::Export, export: &wasmtime_environ::Export,

View File

@@ -238,6 +238,11 @@ impl Mmap {
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.len self.len
} }
/// Return whether any memory has been allocated.
pub fn is_empty(&self) -> bool {
self.len() == 0
}
} }
impl Drop for Mmap { impl Drop for Mmap {

View File

@@ -601,6 +601,7 @@ pub struct VMContext {}
impl VMContext { impl VMContext {
/// Return a mutable reference to the associated `Instance`. /// Return a mutable reference to the associated `Instance`.
/// ///
/// # Safety
/// This is unsafe because it doesn't work on just any `VMContext`, it must /// This is unsafe because it doesn't work on just any `VMContext`, it must
/// be a `VMContext` allocated as part of an `Instance`. /// be a `VMContext` allocated as part of an `Instance`.
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
@@ -610,6 +611,7 @@ impl VMContext {
/// Return a mutable reference to the host state associated with this `Instance`. /// Return a mutable reference to the host state associated with this `Instance`.
/// ///
/// # Safety
/// This is unsafe because it doesn't work on just any `VMContext`, it must /// This is unsafe because it doesn't work on just any `VMContext`, it must
/// be a `VMContext` allocated as part of an `Instance`. /// be a `VMContext` allocated as part of an `Instance`.
pub unsafe fn host_state(&mut self) -> &mut dyn Any { pub unsafe fn host_state(&mut self) -> &mut dyn Any {
@@ -617,6 +619,9 @@ impl VMContext {
} }
/// Lookup an export in the global exports namespace. /// Lookup an export in the global exports namespace.
/// # Safety
/// This is unsafe because it doesn't work on just any `VMContext`, it must
/// be a `VMContext` allocated as part of an `Instance`.
pub unsafe fn lookup_global_export(&mut self, field: &str) -> Option<crate::export::Export> { pub unsafe fn lookup_global_export(&mut self, field: &str) -> Option<crate::export::Export> {
self.instance().lookup_global_export(field) self.instance().lookup_global_export(field)
} }

View File

@@ -86,11 +86,11 @@ pub fn instantiate_spectest(store: &HostRef<Store>) -> HashMap<&'static str, Ext
ret.insert("global_i64", Extern::Global(HostRef::new(g))); ret.insert("global_i64", Extern::Global(HostRef::new(g)));
let ty = GlobalType::new(ValType::F32, Mutability::Const); let ty = GlobalType::new(ValType::F32, Mutability::Const);
let g = Global::new(store, ty, Val::F32(0x44268000)); let g = Global::new(store, ty, Val::F32(0x4426_8000));
ret.insert("global_f32", Extern::Global(HostRef::new(g))); ret.insert("global_f32", Extern::Global(HostRef::new(g)));
let ty = GlobalType::new(ValType::F64, Mutability::Const); let ty = GlobalType::new(ValType::F64, Mutability::Const);
let g = Global::new(store, ty, Val::F64(0x4084d00000000000)); let g = Global::new(store, ty, Val::F64(0x4084_d000_0000_0000));
ret.insert("global_f64", Extern::Global(HostRef::new(g))); ret.insert("global_f64", Extern::Global(HostRef::new(g)));
let ty = TableType::new(ValType::FuncRef, Limits::new(10, Some(20))); let ty = TableType::new(ValType::FuncRef, Limits::new(10, Some(20)));

View File

@@ -301,12 +301,12 @@ impl WastContext {
for v in values.iter() { for v in values.iter() {
match v { match v {
Val::F32(x) => { Val::F32(x) => {
if !is_canonical_f32_nan(x) { if !is_canonical_f32_nan(*x) {
bail!("{}\nexpected canonical NaN", context(span)) bail!("{}\nexpected canonical NaN", context(span))
} }
} }
Val::F64(x) => { Val::F64(x) => {
if !is_canonical_f64_nan(x) { if !is_canonical_f64_nan(*x) {
bail!("{}\nexpected canonical NaN", context(span)) bail!("{}\nexpected canonical NaN", context(span))
} }
} }
@@ -329,7 +329,7 @@ impl WastContext {
other => bail!("expected v128, got {:?}", other), other => bail!("expected v128, got {:?}", other),
}; };
for l in 0..4 { for l in 0..4 {
if !is_canonical_f32_nan(&extract_lane_as_u32(val, l)?) { if !is_canonical_f32_nan(extract_lane_as_u32(val, l)?) {
bail!( bail!(
"{}\nexpected f32x4 canonical NaN in lane {}", "{}\nexpected f32x4 canonical NaN in lane {}",
context(span), context(span),
@@ -354,7 +354,7 @@ impl WastContext {
other => bail!("expected v128, got {:?}", other), other => bail!("expected v128, got {:?}", other),
}; };
for l in 0..2 { for l in 0..2 {
if !is_canonical_f64_nan(&extract_lane_as_u64(val, l)?) { if !is_canonical_f64_nan(extract_lane_as_u64(val, l)?) {
bail!( bail!(
"{}\nexpected f64x2 canonical NaN in lane {}", "{}\nexpected f64x2 canonical NaN in lane {}",
context(span), context(span),
@@ -376,12 +376,12 @@ impl WastContext {
for v in values.iter() { for v in values.iter() {
match v { match v {
Val::F32(x) => { Val::F32(x) => {
if !is_arithmetic_f32_nan(x) { if !is_arithmetic_f32_nan(*x) {
bail!("{}\nexpected arithmetic NaN", context(span)) bail!("{}\nexpected arithmetic NaN", context(span))
} }
} }
Val::F64(x) => { Val::F64(x) => {
if !is_arithmetic_f64_nan(x) { if !is_arithmetic_f64_nan(*x) {
bail!("{}\nexpected arithmetic NaN", context(span)) bail!("{}\nexpected arithmetic NaN", context(span))
} }
} }
@@ -404,7 +404,7 @@ impl WastContext {
other => bail!("expected v128, got {:?}", other), other => bail!("expected v128, got {:?}", other),
}; };
for l in 0..4 { for l in 0..4 {
if !is_arithmetic_f32_nan(&extract_lane_as_u32(val, l)?) { if !is_arithmetic_f32_nan(extract_lane_as_u32(val, l)?) {
bail!( bail!(
"{}\nexpected f32x4 arithmetic NaN in lane {}", "{}\nexpected f32x4 arithmetic NaN in lane {}",
context(span), context(span),
@@ -429,7 +429,7 @@ impl WastContext {
other => bail!("expected v128, got {:?}", other), other => bail!("expected v128, got {:?}", other),
}; };
for l in 0..2 { for l in 0..2 {
if !is_arithmetic_f64_nan(&extract_lane_as_u64(val, l)?) { if !is_arithmetic_f64_nan(extract_lane_as_u64(val, l)?) {
bail!( bail!(
"{}\nexpected f64x2 arithmetic NaN in lane {}", "{}\nexpected f64x2 arithmetic NaN in lane {}",
context(span), context(span),
@@ -538,20 +538,22 @@ fn extract_lane_as_u64(bytes: &u128, lane: usize) -> Result<u64> {
Ok((*bytes >> (lane * 64)) as u64) Ok((*bytes >> (lane * 64)) as u64)
} }
fn is_canonical_f32_nan(bits: &u32) -> bool { fn is_canonical_f32_nan(bits: u32) -> bool {
return (bits & 0x7fffffff) == 0x7fc00000; (bits & 0x7fff_ffff) == 0x7fc0_0000
} }
fn is_canonical_f64_nan(bits: &u64) -> bool { fn is_canonical_f64_nan(bits: u64) -> bool {
return (bits & 0x7fffffffffffffff) == 0x7ff8000000000000; (bits & 0x7fff_ffff_ffff_ffff) == 0x7ff8_0000_0000_0000
} }
fn is_arithmetic_f32_nan(bits: &u32) -> bool { fn is_arithmetic_f32_nan(bits: u32) -> bool {
return (bits & 0x00400000) == 0x00400000; const AF32_NAN: u32 = 0x0040_0000;
(bits & AF32_NAN) == AF32_NAN
} }
fn is_arithmetic_f64_nan(bits: &u64) -> bool { fn is_arithmetic_f64_nan(bits: u64) -> bool {
return (bits & 0x0008000000000000) == 0x0008000000000000; const AF64_NAN: u64 = 0x0008_0000_0000_0000;
(bits & AF64_NAN) == AF64_NAN
} }
fn values_equal(v1: &Val, v2: &Val) -> Result<bool> { fn values_equal(v1: &Val, v2: &Val) -> Result<bool> {

View File

@@ -12,10 +12,7 @@
)] )]
#![warn(unused_import_braces)] #![warn(unused_import_braces)]
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../clippy.toml")))] #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../clippy.toml")))]
#![cfg_attr( #![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))]
feature = "cargo-clippy",
allow(clippy::new_without_default, clippy::new_without_default_derive)
)]
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
warn( warn(
@@ -287,7 +284,7 @@ fn handle_module(
emit_debugsections( emit_debugsections(
&mut obj, &mut obj,
&module_vmctx_info, &module_vmctx_info,
&target_config, target_config,
&debug_data, &debug_data,
&address_transform, &address_transform,
&value_ranges, &value_ranges,

View File

@@ -13,10 +13,7 @@
)] )]
#![warn(unused_import_braces)] #![warn(unused_import_braces)]
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../clippy.toml")))] #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../clippy.toml")))]
#![cfg_attr( #![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))]
feature = "cargo-clippy",
allow(clippy::new_without_default, clippy::new_without_default_derive)
)]
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
warn( warn(
@@ -373,8 +370,7 @@ fn handle_module(
.borrow() .borrow()
.exports() .exports()
.iter() .iter()
.find(|export| export.name().is_empty()) .any(|export| export.name().is_empty())
.is_some()
{ {
// Launch the default command export. // Launch the default command export.
let data = ModuleData::new(&data)?; let data = ModuleData::new(&data)?;
@@ -405,7 +401,7 @@ fn invoke_export(
// the CLI parameters and attempt to parse them into function arguments for // the CLI parameters and attempt to parse them into function arguments for
// the function we'll invoke. // the function we'll invoke.
let binding = data.binding_for_export(&mut handle, name)?; let binding = data.binding_for_export(&mut handle, name)?;
if binding.param_types()?.len() > 0 { if !binding.param_types()?.is_empty() {
eprintln!( eprintln!(
"warning: using `--invoke` with a function that takes arguments \ "warning: using `--invoke` with a function that takes arguments \
is experimental and may break in the future" is experimental and may break in the future"
@@ -443,7 +439,7 @@ fn invoke_export(
let results = data let results = data
.invoke_export(&instance, name, &values) .invoke_export(&instance, name, &values)
.with_context(|| format!("failed to invoke `{}`", name))?; .with_context(|| format!("failed to invoke `{}`", name))?;
if results.len() > 0 { if !results.is_empty() {
eprintln!( eprintln!(
"warning: using `--invoke` with a function that returns values \ "warning: using `--invoke` with a function that returns values \
is experimental and may break in the future" is experimental and may break in the future"

View File

@@ -8,10 +8,7 @@
)] )]
#![warn(unused_import_braces)] #![warn(unused_import_braces)]
#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))] #![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
#![cfg_attr( #![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))]
feature = "cargo-clippy",
allow(clippy::new_without_default, clippy::new_without_default_derive)
)]
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
warn( warn(