diff options
Diffstat (limited to 'tamer/src')
-rw-r--r-- | tamer/src/ld/poc.rs | 63 | ||||
-rw-r--r-- | tamer/src/obj/xmlo/asg_builder.rs | 39 | ||||
-rw-r--r-- | tamer/src/obj/xmlo/mod.rs | 2 |
3 files changed, 39 insertions, 65 deletions
diff --git a/tamer/src/ld/poc.rs b/tamer/src/ld/poc.rs index 38ac2b3..e924632 100644 --- a/tamer/src/ld/poc.rs +++ b/tamer/src/ld/poc.rs @@ -25,12 +25,12 @@ use crate::fs::{ }; use crate::global; use crate::ir::asg::{ - Asg, AsgError, DefaultAsg, IdentObject, IdentObjectData, ObjectRef, - Sections, SortableAsg, + Asg, AsgError, DefaultAsg, IdentObject, IdentObjectData, Sections, + SortableAsg, }; use crate::obj::xmle::writer::XmleWriter; use crate::obj::xmlo::reader::{XmloError, XmloReader}; -use crate::obj::xmlo::{AsgBuilder, AsgBuilderResult}; +use crate::obj::xmlo::{AsgBuilder, AsgBuilderState}; use crate::sym::{DefaultInterner, Interner, Symbol}; use fxhash::{FxBuildHasher, FxHashMap}; use std::error::Error; @@ -39,39 +39,33 @@ use std::io::BufReader; use std::path::PathBuf; type LinkerAsg<'i> = DefaultAsg<'i, IdentObject<'i>, global::ProgIdentSize>; -type LinkerObjectRef = ObjectRef<global::ProgIdentSize>; -type LoadResult<'i> = - Result<Option<(Option<&'i Symbol<'i>>, Option<String>)>, Box<dyn Error>>; +type LinkerAsgBuilderState<'i> = + AsgBuilderState<'i, FxBuildHasher, global::ProgIdentSize>; pub fn main(package_path: &str, output: &str) -> Result<(), Box<dyn Error>> { let mut fs = VisitOnceFilesystem::new(); let mut fragments: FxHashMap<&str, String> = Default::default(); let mut depgraph = LinkerAsg::with_capacity(65536, 65536); - let mut roots = Vec::new(); let interner = DefaultInterner::new(); let abs_path = fs::canonicalize(package_path)?; - let (name, relroot) = load_xmlo( + let state = load_xmlo( &abs_path.to_str().unwrap().to_string(), &mut fs, &mut fragments, &mut depgraph, &interner, - &mut roots, - )? - .expect("missing root package information"); - - // println!( - // "Graph {:?}", - // depgraph - // .graph - // .raw_nodes() - // .iter() - // .map(|node| &node.weight) - // .collect::<Vec<_>>() - // ); + Default::default(), + )?; + + let AsgBuilderState { + mut roots, + name, + relroot, + found: _, + } = state; roots.extend( vec!["___yield", "___worksheet"] @@ -127,31 +121,24 @@ fn load_xmlo<'a, 'i, I: Interner<'i>>( fragments: &mut FxHashMap<&'i str, String>, depgraph: &mut LinkerAsg<'i>, interner: &'i I, - roots: &mut Vec<LinkerObjectRef>, -) -> LoadResult<'i> { - let first = fs.visit_len() == 0; - + state: LinkerAsgBuilderState<'i>, +) -> Result<LinkerAsgBuilderState<'i>, Box<dyn Error>> { let cfile: CanonicalFile<BufReader<fs::File>> = match fs.open(path_str)? { VisitOnceFile::FirstVisit(file) => file, - VisitOnceFile::Visited => return Ok(None), + VisitOnceFile::Visited => return Ok(state), }; let (path, file) = cfile.into(); let xmlo: XmloReader<'_, _, _> = (file, interner).into(); - let AsgBuilderResult::<'i, FxBuildHasher, _> { - found, - roots: mut pkgroots, - name, - relroot, - } = xmlo.build(depgraph, first)?; - - roots.append(&mut pkgroots); + let mut state = xmlo.build(depgraph, state)?; let mut dir: PathBuf = path.clone(); dir.pop(); + let found = state.found.take().unwrap_or_default(); + for relpath in found.iter() { let mut path_buf = dir.clone(); path_buf.push(relpath); @@ -161,14 +148,10 @@ fn load_xmlo<'a, 'i, I: Interner<'i>>( let path_abs = path_buf.canonicalize()?; let path = path_abs.to_str().unwrap(); - load_xmlo(path, fs, fragments, depgraph, interner, roots)?; + state = load_xmlo(path, fs, fragments, depgraph, interner, state)?; } - if first { - Ok(Some((name, relroot))) - } else { - Ok(None) - } + Ok(state) } fn get_ident<'a, 'i>( diff --git a/tamer/src/obj/xmlo/asg_builder.rs b/tamer/src/obj/xmlo/asg_builder.rs index af37b58..1f50249 100644 --- a/tamer/src/obj/xmlo/asg_builder.rs +++ b/tamer/src/obj/xmlo/asg_builder.rs @@ -29,15 +29,16 @@ use std::io::BufRead; // TODO error type pub type Result<'i, S, Ix> = - std::result::Result<AsgBuilderResult<'i, S, Ix>, Box<dyn Error>>; + std::result::Result<AsgBuilderState<'i, S, Ix>, Box<dyn Error>>; -pub struct AsgBuilderResult<'i, S, Ix> +#[derive(Debug, Default)] +pub struct AsgBuilderState<'i, S, Ix> where - S: BuildHasher + Default, + S: BuildHasher, Ix: IndexType, { pub roots: Vec<ObjectRef<Ix>>, - pub found: HashSet<&'i str, S>, + pub found: Option<HashSet<&'i str, S>>, pub name: Option<&'i Symbol<'i>>, pub relroot: Option<String>, } @@ -45,13 +46,13 @@ where pub trait AsgBuilder<'i, O, S, Ix> where O: IdentObjectState<'i, O>, - S: BuildHasher + Default, + S: BuildHasher, Ix: IndexType, { fn build<G: Asg<'i, O, Ix>>( self, graph: &mut G, - first: bool, + state: AsgBuilderState<'i, S, Ix>, ) -> Result<'i, S, Ix>; } @@ -63,27 +64,22 @@ where S: BuildHasher + Default, Ix: IndexType, { - // TOOD: remove first fn build<G: Asg<'i, O, Ix>>( mut self, graph: &mut G, - first: bool, + mut state: AsgBuilderState<'i, S, Ix>, ) -> Result<'i, S, Ix> { - // TODO - let mut found: HashSet<&'i str, S> = Default::default(); - - let mut roots = Vec::new(); let mut elig = None; + let first = state.name.is_none(); - let mut name: Option<&'i Symbol<'i>> = None; - let mut relroot: Option<String> = None; + let found = state.found.get_or_insert(Default::default()); loop { match self.read_event() { Ok(XmloEvent::Package(attrs)) => { if first { - name = attrs.name; - relroot = attrs.relroot; + state.name = attrs.name; + state.relroot = attrs.relroot; } elig = attrs.elig; } @@ -135,7 +131,7 @@ where graph.declare(sym, kindval, src)?; if link_root { - roots.push(node); + state.roots.push(node); } } } @@ -168,16 +164,11 @@ where } if let Some(elig_sym) = elig { - roots.push(graph.lookup(elig_sym).expect( + state.roots.push(graph.lookup(elig_sym).expect( "internal error: package elig references nonexistant symbol", )); } - Ok(AsgBuilderResult { - roots, - found, - name, - relroot, - }) + Ok(state) } } diff --git a/tamer/src/obj/xmlo/mod.rs b/tamer/src/obj/xmlo/mod.rs index a30ab7b..113c9c7 100644 --- a/tamer/src/obj/xmlo/mod.rs +++ b/tamer/src/obj/xmlo/mod.rs @@ -77,4 +77,4 @@ pub mod reader; mod asg_builder; -pub use asg_builder::{AsgBuilder, AsgBuilderResult}; +pub use asg_builder::{AsgBuilder, AsgBuilderState}; |