Avoid allocating a temporary Vec in the parser.

Wrangle the borrow checker into allowing us to iterate over function result
values while mutating the ctx.values table.
This commit is contained in:
Jakob Stoklund Olesen
2016-06-01 20:45:58 -07:00
parent ecd8287eb0
commit 4eb327d027

View File

@@ -577,13 +577,11 @@ impl<'a> Parser<'a> {
} }
// Now map the source result values to the just created instruction results. // Now map the source result values to the just created instruction results.
// We need to copy the list of result values to avoid fighting the borrow checker. // Pass a reference to `ctx.values` instead of `ctx` itself since the `Values` iterator
let new_results: Vec<Value> = ctx.function.inst_results(inst).collect(); // holds a reference to `ctx.function`.
for (src, val) in results.iter().zip(new_results) { self.add_values(&mut ctx.values,
try!(ctx.add_value(*src, val, &self.location)); results.into_iter(),
} ctx.function.inst_results(inst))
Ok(())
} }
// Type inference for polymorphic instructions. // Type inference for polymorphic instructions.
@@ -650,6 +648,24 @@ impl<'a> Parser<'a> {
Ok(ctrl_type) Ok(ctrl_type)
} }
// Add mappings for a list of source values to their corresponding new values.
fn add_values<S, V>(&self,
values: &mut HashMap<Value, Value>,
results: S,
new_results: V)
-> Result<()>
where S: Iterator<Item = Value>,
V: Iterator<Item = Value>
{
for (src, val) in results.zip(new_results) {
if values.insert(src, val).is_some() {
return Err(self.error_string(format!("duplicate result value: {}", src)));
}
}
Ok(())
}
// Parse the operands following the instruction opcode. // Parse the operands following the instruction opcode.
// This depends on the format of the opcode. // This depends on the format of the opcode.
fn parse_inst_operands(&mut self, opcode: Opcode) -> Result<InstructionData> { fn parse_inst_operands(&mut self, opcode: Opcode) -> Result<InstructionData> {