tamer: Read only a single map preproc:from from xmlo files

This was creating a heap-allocated `Vec` for each map symbol despite not
actually needing it.  We do have multiple froms for return map values.

But by the time we may want this type of thing, we'll have a different IR
for it anyway.
main
Mike Gerwitz 2021-10-04 14:59:33 -04:00
parent 772619f6f0
commit 004f5dc312
5 changed files with 41 additions and 46 deletions

View File

@ -657,7 +657,7 @@ pub struct Source {
///
/// TODO: We have `parent`, `yields`, and `from`.
/// We should begin to consolodate.
pub from: Option<Vec<SymbolId>>,
pub from: Option<SymbolId>,
/// Whether identifier is virtual (can be overridden).
///
@ -1665,7 +1665,7 @@ mod test {
parent: Some(psym),
yields: Some(ysym),
desc: Some("sym desc".into()),
from: Some(vec![fsym]),
from: Some(fsym),
virtual_: true,
override_: true,
..Default::default()
@ -1679,7 +1679,7 @@ mod test {
parent: attrs.parent,
yields: attrs.yields,
desc: Some("sym desc".into()),
from: Some(vec![fsym]),
from: Some(fsym),
virtual_: true,
override_: true,
},

View File

@ -159,7 +159,9 @@ pub struct SymAttrs {
/// - [`SymType::Map`] includes the name of the source field; and
/// - [`SymType::Func`] lists params in order (so that the compiler
/// knows application order).
pub from: Option<Vec<SymbolId>>,
///
/// This system currently only handles the former.
pub from: Option<SymbolId>,
/// Whether symbol can be overridden.
///

View File

@ -302,19 +302,12 @@ impl<W: Write> XmleWriter<W> {
&mut self,
sections: &Sections<T>,
) -> Result<&mut XmleWriter<W>> {
let mut map_froms: FxHashSet<SymbolId> = Default::default();
let map_iter = sections.iter_map();
for map_ident in map_iter {
let src = map_ident.src().expect("internal error: missing map src");
if let Some(froms) = &src.from {
for from in froms {
map_froms.insert(*from);
}
}
}
let map_froms: FxHashSet<SymbolId> = sections
.iter_map()
.filter_map(|ident| {
ident.src().expect("internal error: missing map src").from
})
.collect();
for from in map_froms {
let name: &str = &from.lookup_str();
@ -650,7 +643,7 @@ mod test {
parent: Some(psym),
yields: Some(ysym),
desc: Some("sym desc".into()),
from: Some(vec![fsym]),
from: Some(fsym),
virtual_: true,
..Default::default()
};
@ -688,7 +681,7 @@ mod test {
let symb = "dest symbol".intern();
let mut src = Source::default();
src.from = Some(vec![symb]);
src.from = Some(symb);
let object = IdentObject::Ident(sym, IdentKind::Worksheet, src);
let mut sections = Sections::new();
sections.map.push_body(&object);

View File

@ -313,10 +313,10 @@ where
XmloEvent::SymDecl(_, attrs)
if attrs.ty == Some(SymType::Map) =>
{
attrs.from = Some(Self::process_map_from(
attrs.from = Self::process_map_from(
&mut self.reader,
&mut self.sub_buffer,
)?);
)?;
Ok(event)
}
@ -502,13 +502,22 @@ where
fn process_map_from<'a>(
reader: &mut XmlReader<B>,
buffer: &mut Vec<u8>,
) -> XmloResult<Vec<SymbolId>> {
let mut froms = Vec::new();
) -> XmloResult<Option<SymbolId>> {
let mut from = None;
loop {
match reader.read_event(buffer)? {
XmlEvent::Empty(ele) if ele.name() == b"preproc:from" => froms
.push(
XmlEvent::Empty(ele) if ele.name() == b"preproc:from" => {
if from.is_some() {
// This feature isn't actually utilized for the
// input map.
return Err(XmloError::InvalidMapFrom(
"multiple preproc:from found for input map entry"
.into(),
));
}
from.replace(
ele.attributes()
.with_checks(false)
.filter_map(Result::ok)
@ -523,7 +532,8 @@ where
})
},
)?,
),
);
}
XmlEvent::End(ele) if ele.name() == b"preproc:sym" => break,
@ -534,7 +544,7 @@ where
};
}
Ok(froms)
Ok(from)
}
/// Process `preproc:sym-dep` element.

View File

@ -487,7 +487,12 @@ xmlo_tests! {
])),
))),
1 => Ok(XmlEvent::Empty(MockBytesStart::new(
// make sure that whitespace is permitted
1 => Ok(XmlEvent::Text(MockBytesText::new(
b" ",
))),
2 => Ok(XmlEvent::Empty(MockBytesStart::new(
b"preproc:from",
Some(MockAttributes::new(vec![
MockAttribute::new(
@ -496,21 +501,7 @@ xmlo_tests! {
])),
))),
// make sure that whitespace is permitted
2 => Ok(XmlEvent::Text(MockBytesText::new(
b" ",
))),
3 => Ok(XmlEvent::Empty(MockBytesStart::new(
b"preproc:from",
Some(MockAttributes::new(vec![
MockAttribute::new(
b"name", b"from-b",
),
])),
))),
4 => Ok(XmlEvent::End(MockBytesEnd::new(
3 => Ok(XmlEvent::End(MockBytesEnd::new(
b"preproc:sym",
))),
@ -526,10 +517,9 @@ xmlo_tests! {
"sym-map-from".intern(),
SymAttrs {
ty: Some(SymType::Map),
from: Some(vec![
from: Some(
"from-a".intern(),
"from-b".intern(),
]),
),
pkg_name: Some("pkg/name".intern()),
..Default::default()
},