Mike Gerwitz

Activist for User Freedom

aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tamer/src/ld/poc.rs63
-rw-r--r--tamer/src/obj/xmlo/asg_builder.rs39
-rw-r--r--tamer/src/obj/xmlo/mod.rs2
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};