Removed the Opcode::NotAnOpcode variant, replaced its uses with Option<Opcode>, and used the NonZero optimization to maintain the small 1-byte size of an optional Opcode.

This commit is contained in:
Angus Holder
2017-02-22 16:13:48 +00:00
committed by Jakob Stoklund Olesen
parent 3d0240d244
commit a4e4776087
6 changed files with 30 additions and 32 deletions

View File

@@ -43,12 +43,8 @@ impl Display for Opcode {
impl Opcode {
/// Get the instruction format for this opcode.
pub fn format(self) -> Option<InstructionFormat> {
if self == Opcode::NotAnOpcode {
None
} else {
Some(OPCODE_FORMAT[self as usize - 1])
}
pub fn format(self) -> InstructionFormat {
OPCODE_FORMAT[self as usize - 1]
}
/// Get the constraint descriptor for this opcode.
@@ -69,23 +65,21 @@ impl FromStr for Opcode {
fn from_str(s: &str) -> Result<Opcode, &'static str> {
use constant_hash::{Table, simple_hash, probe};
impl<'a> Table<&'a str> for [Opcode] {
impl<'a> Table<&'a str> for [Option<Opcode>] {
fn len(&self) -> usize {
self.len()
}
fn key(&self, idx: usize) -> Option<&'a str> {
if self[idx] == Opcode::NotAnOpcode {
None
} else {
Some(opcode_name(self[idx]))
}
self[idx].map(opcode_name)
}
}
match probe::<&str, [Opcode]>(&OPCODE_HASH_TABLE, s, simple_hash(s)) {
match probe::<&str, [Option<Opcode>]>(&OPCODE_HASH_TABLE, s, simple_hash(s)) {
None => Err("Unknown opcode"),
Some(i) => Ok(OPCODE_HASH_TABLE[i]),
// We unwrap here because probe() should have ensured that the entry
// at this index is not None.
Some(i) => Ok(OPCODE_HASH_TABLE[i].unwrap()),
}
}
}

View File

@@ -53,7 +53,7 @@ impl<OffT: Into<u32> + Copy> Table<Type> for [Level1Entry<OffT>] {
///
/// Empty entries are encoded with a `NotAnOpcode` `opcode` field.
pub struct Level2Entry<OffT: Into<u32> + Copy> {
pub opcode: Opcode,
pub opcode: Option<Opcode>,
pub offset: OffT,
}
@@ -63,12 +63,7 @@ impl<OffT: Into<u32> + Copy> Table<Opcode> for [Level2Entry<OffT>] {
}
fn key(&self, idx: usize) -> Option<Opcode> {
let opc = self[idx].opcode;
if opc != Opcode::NotAnOpcode {
Some(opc)
} else {
None
}
self[idx].opcode
}
}

View File

@@ -149,7 +149,7 @@ impl<'a> Verifier<'a> {
let inst_data = &self.func.dfg[inst];
// The instruction format matches the opcode
if inst_data.opcode().format() != Some(InstructionFormat::from(inst_data)) {
if inst_data.opcode().format() != InstructionFormat::from(inst_data) {
return err!(inst, "instruction opcode doesn't match instruction format");
}