mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-04-17 06:26:35 +00:00
refactor(msl-out): create a type for bounds check iter items
Co-Authored-By: Erich Gubler <erichdongubler@gmail.com>
This commit is contained in:
parent
a7afb56276
commit
a0dbe5ebc6
@ -18,7 +18,11 @@ use crate::{
|
||||
arena::{Handle, HandleSet},
|
||||
back::{self, Baked},
|
||||
common,
|
||||
proc::{self, index, NameKey, TypeResolution},
|
||||
proc::{
|
||||
self,
|
||||
index::{self, BoundsCheck},
|
||||
NameKey, TypeResolution,
|
||||
},
|
||||
valid, FastHashMap, FastHashSet,
|
||||
};
|
||||
|
||||
@ -723,13 +727,7 @@ impl<'a> ExpressionContext<'a> {
|
||||
fn bounds_check_iter(
|
||||
&self,
|
||||
chain: Handle<crate::Expression>,
|
||||
) -> impl Iterator<
|
||||
Item = (
|
||||
Handle<crate::Expression>,
|
||||
index::GuardedIndex,
|
||||
index::IndexableLength,
|
||||
),
|
||||
> + '_ {
|
||||
) -> impl Iterator<Item = BoundsCheck> + '_ {
|
||||
index::bounds_check_iter(chain, self.module, self.function, self.info)
|
||||
}
|
||||
|
||||
@ -2778,7 +2776,13 @@ impl<W: Write> Writer<W> {
|
||||
let mut check_written = false;
|
||||
|
||||
// Iterate over the access chain, handling each required bounds check.
|
||||
for (base, index, length) in context.bounds_check_iter(chain) {
|
||||
for item in context.bounds_check_iter(chain) {
|
||||
let BoundsCheck {
|
||||
base,
|
||||
index,
|
||||
length,
|
||||
} = item;
|
||||
|
||||
if check_written {
|
||||
write!(self.out, " && ")?;
|
||||
} else {
|
||||
|
@ -342,12 +342,27 @@ pub fn access_needs_check(
|
||||
Some(length)
|
||||
}
|
||||
|
||||
/// Items returned by the [`bounds_check_iter`] iterator.
|
||||
#[cfg_attr(not(feature = "msl-out"), allow(dead_code))]
|
||||
pub(crate) struct BoundsCheck {
|
||||
/// The base of the [`Access`] or [`AccessIndex`] expression.
|
||||
///
|
||||
/// [`Access`]: crate::Expression::Access
|
||||
/// [`AccessIndex`]: crate::Expression::AccessIndex
|
||||
pub base: Handle<crate::Expression>,
|
||||
|
||||
/// The index being accessed.
|
||||
pub index: GuardedIndex,
|
||||
|
||||
/// The length of `base`.
|
||||
pub length: IndexableLength,
|
||||
}
|
||||
|
||||
/// Returns an iterator of accesses within the chain of `Access` and
|
||||
/// `AccessIndex` expressions starting from `chain` that may need to be
|
||||
/// bounds-checked at runtime.
|
||||
///
|
||||
/// They're yielded as `(base, index)` pairs, where `base` is the type that the
|
||||
/// access expression will produce and `index` is the index being used.
|
||||
/// Items are yielded as [`BoundsCheck`] instances.
|
||||
///
|
||||
/// Accesses through a struct are omitted, since you never need a bounds check
|
||||
/// for accessing a struct field.
|
||||
@ -359,7 +374,7 @@ pub(crate) fn bounds_check_iter<'a>(
|
||||
module: &'a crate::Module,
|
||||
function: &'a crate::Function,
|
||||
info: &'a valid::FunctionInfo,
|
||||
) -> impl Iterator<Item = (Handle<crate::Expression>, GuardedIndex, IndexableLength)> + 'a {
|
||||
) -> impl Iterator<Item = BoundsCheck> + 'a {
|
||||
iter::from_fn(move || {
|
||||
let (next_expr, result) = match function.expressions[chain] {
|
||||
crate::Expression::Access { base, index } => {
|
||||
@ -384,8 +399,13 @@ pub(crate) fn bounds_check_iter<'a>(
|
||||
})
|
||||
.flatten()
|
||||
.filter_map(|(base, index)| {
|
||||
access_needs_check(base, index, module, &function.expressions, info)
|
||||
.map(|length| (base, index, length))
|
||||
access_needs_check(base, index, module, &function.expressions, info).map(|length| {
|
||||
BoundsCheck {
|
||||
base,
|
||||
index,
|
||||
length,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user