diff --git a/core/src/avm2/globals/vector.rs b/core/src/avm2/globals/vector.rs index 4506d575e..3dab1ae4e 100644 --- a/core/src/avm2/globals/vector.rs +++ b/core/src/avm2/globals/vector.rs @@ -329,7 +329,7 @@ where let string_separator = separator.coerce_to_string(activation)?; let mut accum = Vec::with_capacity(vector.length()); - for (_, item) in vector.iter().enumerate() { + for item in vector.iter() { if matches!(item, Value::Undefined) || matches!(item, Value::Null) { accum.push("null".into()); } else { diff --git a/core/src/lib.rs b/core/src/lib.rs index 77db3d9e0..31fbc3f67 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -3,6 +3,9 @@ // This lint is helpful, but right now we have too many instances of it. // TODO: Remove this once all instances are fixed. #![allow(clippy::needless_pass_by_ref_mut)] +// This lint is good in theory, but in AVMs we often need to do `let x = args.get(0); let y = args.get(1);` etc. +// It'd make those much less readable and consistent. +#![allow(clippy::get_first)] #[macro_use] mod display_object; diff --git a/core/src/string/interner.rs b/core/src/string/interner.rs index e7e8300d6..2e5e96721 100644 --- a/core/src/string/interner.rs +++ b/core/src/string/interner.rs @@ -116,9 +116,7 @@ struct WeakSet<'gc, T: 'gc> { impl<'gc, T: Hash + 'gc> WeakSet<'gc, T> { fn hash(build_hasher: &impl BuildHasher, key: &K) -> u64 { - let mut hasher = build_hasher.build_hasher(); - key.hash(&mut hasher); - hasher.finish() + build_hasher.hash_one(key) } /// Finds the given key in the map. diff --git a/exporter/src/main.rs b/exporter/src/main.rs index 14ce94193..e9cdf9b68 100644 --- a/exporter/src/main.rs +++ b/exporter/src/main.rs @@ -239,7 +239,7 @@ fn capture_single_swf(descriptors: Arc, opt: &Opt) -> Result<()> { } if frames.len() == 1 { - let image = frames.get(0).unwrap(); + let image = frames.first().unwrap(); if opt.output_path == Some(PathBuf::from("-")) { let mut bytes: Vec = Vec::new(); image @@ -343,7 +343,7 @@ fn capture_multiple_swfs(descriptors: Arc, opt: &Opt) -> Result<()> if let Some(parent) = destination.parent() { let _ = create_dir_all(parent); } - frames.get(0).unwrap().save(&destination)?; + frames.first().unwrap().save(&destination)?; } else { let mut parent: PathBuf = (&output).into(); relative_path.set_extension(""); diff --git a/render/src/matrix.rs b/render/src/matrix.rs index 879823cee..914fed7ed 100644 --- a/render/src/matrix.rs +++ b/render/src/matrix.rs @@ -257,6 +257,57 @@ impl std::ops::MulAssign for Matrix { } } +impl From for Matrix { + fn from(matrix: swf::Matrix) -> Self { + Self { + a: matrix.a.to_f32(), + b: matrix.b.to_f32(), + c: matrix.c.to_f32(), + d: matrix.d.to_f32(), + tx: matrix.tx, + ty: matrix.ty, + } + } +} + +impl From for swf::Matrix { + fn from(matrix: Matrix) -> Self { + Self { + a: Fixed16::from_f32(matrix.a), + b: Fixed16::from_f32(matrix.b), + c: Fixed16::from_f32(matrix.c), + d: Fixed16::from_f32(matrix.d), + tx: matrix.tx, + ty: matrix.ty, + } + } +} + +/// Implements the IEEE-754 "Round to nearest, ties to even" rounding rule. +/// (e.g., both 1.5 and 2.5 will round to 2). +/// This is the rounding method used by Flash for the above transforms. +/// Although this is easy to do on most architectures, Rust provides no standard +/// way to round in this manner (`f32::round` always rounds away from zero). +/// For more info and the below code snippet, see: https://github.com/rust-lang/rust/issues/55107 +/// This also clamps out-of-range values and NaN to `i32::MIN`. +/// TODO: Investigate using SSE/wasm intrinsics for this. +fn round_to_i32(f: f32) -> i32 { + if f.is_finite() { + let a = f.abs(); + if f < 2_147_483_648.0_f32 { + let k = 1.0 / f32::EPSILON; + let out = if a < k { ((a + k) - k).copysign(f) } else { f }; + out as i32 + } else { + // Out-of-range clamps to MIN. + i32::MIN + } + } else { + // NaN/Infinity goes to 0. + 0 + } +} + #[cfg(test)] mod tests { use super::*; @@ -907,54 +958,3 @@ mod tests { ), ); } - -impl From for Matrix { - fn from(matrix: swf::Matrix) -> Self { - Self { - a: matrix.a.to_f32(), - b: matrix.b.to_f32(), - c: matrix.c.to_f32(), - d: matrix.d.to_f32(), - tx: matrix.tx, - ty: matrix.ty, - } - } -} - -impl From for swf::Matrix { - fn from(matrix: Matrix) -> Self { - Self { - a: Fixed16::from_f32(matrix.a), - b: Fixed16::from_f32(matrix.b), - c: Fixed16::from_f32(matrix.c), - d: Fixed16::from_f32(matrix.d), - tx: matrix.tx, - ty: matrix.ty, - } - } -} - -/// Implements the IEEE-754 "Round to nearest, ties to even" rounding rule. -/// (e.g., both 1.5 and 2.5 will round to 2). -/// This is the rounding method used by Flash for the above transforms. -/// Although this is easy to do on most architectures, Rust provides no standard -/// way to round in this manner (`f32::round` always rounds away from zero). -/// For more info and the below code snippet, see: https://github.com/rust-lang/rust/issues/55107 -/// This also clamps out-of-range values and NaN to `i32::MIN`. -/// TODO: Investigate using SSE/wasm intrinsics for this. -fn round_to_i32(f: f32) -> i32 { - if f.is_finite() { - let a = f.abs(); - if f < 2_147_483_648.0_f32 { - let k = 1.0 / f32::EPSILON; - let out = if a < k { ((a + k) - k).copysign(f) } else { f }; - out as i32 - } else { - // Out-of-range clamps to MIN. - i32::MIN - } - } else { - // NaN/Infinity goes to 0. - 0 - } -}