use crate::Error;
use super::{Graph, Ref, Type};
pub fn run_checks(graph: &mut Graph) -> Result<(), Error> {
topsort(graph)?;
types(graph)?;
pointers(graph)?;
mappings_initialized(graph)?;
resources_initialized(graph)?;
Ok(())
}
fn types(graph: &mut Graph) -> Result<(), Error> {
for node_id in 0..graph.nodes.len() {
let mut node = graph.nodes[node_id].clone();
let arg_types = node
.args
.iter()
.map(|&r| graph.type_of(r))
.collect::<Vec<_>>();
if let Some(ty) = node.op.annotate(node_id, graph, &arg_types) {
if ty != node.ty {
return Err(Error::Type(node.op, arg_types));
}
}
graph.nodes[node_id] = node;
}
Ok(())
}
fn topsort(graph: &Graph) -> Result<(), Error> {
for (node_id, node) in graph.nodes.iter().enumerate() {
for arg in &node.args {
if let &Ref::Node(arg_id) = arg {
if arg_id >= node_id {
return Err(format!(
"graph topsort violated: node {node_id} references node {arg_id}"
)
.into());
}
}
}
}
Ok(())
}
fn pointers(graph: &Graph) -> Result<(), Error> {
for &input in &graph.inputs {
if matches!(input, Type::Ptr { .. }) {
return Err("found pointer type in input".to_string().into());
}
}
for &output in &graph.outputs {
if matches!(graph.type_of(output), Type::Ptr { .. }) {
return Err("found pointer type in output".to_string().into());
}
}
for node in &graph.nodes {
for arg in &node.args {
if let &Ref::Const(Type::Ptr { .. }, ptr) = arg {
if ptr != 0 {
return Err(format!("found hardcoded non-null pointer in node {node:?}").into());
}
}
}
}
Ok(())
}
fn mappings_initialized(graph: &Graph) -> Result<(), Error> {
for (name, mapping) in &graph.mappings {
if !mapping.is_initialized() {
return Err(
format!("while reading zip archive, mapping {name} was not initialized").into(),
);
}
}
Ok(())
}
fn resources_initialized(graph: &Graph) -> Result<(), Error> {
for (name, resource) in &graph.resources {
if !resource.is_initialized() {
return Err(
format!("while reading zip archive, resource {name} was not initialized").into(),
);
}
}
Ok(())
}