add rules with forbid operations

This commit is contained in:
NikVolf
2018-02-19 19:28:12 +03:00
parent bc475275c1
commit 9e92237c4d
5 changed files with 149 additions and 209 deletions
+91 -56
View File
@@ -3,6 +3,13 @@ use parity_wasm::elements;
pub struct UnknownInstruction;
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum Metering {
Regular,
Forbidden,
Fixed(u32),
}
#[derive(Debug, Hash, PartialEq, Eq, Copy, Clone)]
pub enum InstructionType {
Bit,
@@ -12,13 +19,15 @@ pub enum InstructionType {
Load,
Store,
Const,
FloatConst,
Local,
Global,
ControlFlow,
IntegerComparsion,
FloatComparsion,
Numeric,
Float,
Conversion,
FloatConversion,
Reinterpretation,
Unreachable,
Nop,
@@ -43,8 +52,9 @@ impl ::std::str::FromStr for InstructionType {
"flow" => Ok(InstructionType::ControlFlow),
"integer_comp" => Ok(InstructionType::IntegerComparsion),
"float_comp" => Ok(InstructionType::FloatComparsion),
"numeric" => Ok(InstructionType::Numeric),
"float" => Ok(InstructionType::Float),
"conversion" => Ok(InstructionType::Conversion),
"float_conversion" => Ok(InstructionType::FloatConversion),
"reinterpret" => Ok(InstructionType::Reinterpretation),
"unreachable" => Ok(InstructionType::Unreachable),
"nop" => Ok(InstructionType::Nop),
@@ -112,8 +122,9 @@ impl InstructionType {
I32Const(_) => InstructionType::Const,
I64Const(_) => InstructionType::Const,
F32Const(_) => InstructionType::Const,
F64Const(_) => InstructionType::Const,
F32Const(_) => InstructionType::FloatConst,
F64Const(_) => InstructionType::FloatConst,
I32Eqz => InstructionType::IntegerComparsion,
I32Eq => InstructionType::IntegerComparsion,
@@ -191,56 +202,57 @@ impl InstructionType {
I64Rotl => InstructionType::Bit,
I64Rotr => InstructionType::Bit,
F32Abs => InstructionType::Numeric,
F32Neg => InstructionType::Numeric,
F32Ceil => InstructionType::Numeric,
F32Floor => InstructionType::Numeric,
F32Trunc => InstructionType::Numeric,
F32Nearest => InstructionType::Numeric,
F32Sqrt => InstructionType::Numeric,
F32Add => InstructionType::Numeric,
F32Sub => InstructionType::Numeric,
F32Mul => InstructionType::Numeric,
F32Div => InstructionType::Numeric,
F32Min => InstructionType::Numeric,
F32Max => InstructionType::Numeric,
F32Copysign => InstructionType::Numeric,
F64Abs => InstructionType::Numeric,
F64Neg => InstructionType::Numeric,
F64Ceil => InstructionType::Numeric,
F64Floor => InstructionType::Numeric,
F64Trunc => InstructionType::Numeric,
F64Nearest => InstructionType::Numeric,
F64Sqrt => InstructionType::Numeric,
F64Add => InstructionType::Numeric,
F64Sub => InstructionType::Numeric,
F64Mul => InstructionType::Numeric,
F64Div => InstructionType::Numeric,
F64Min => InstructionType::Numeric,
F64Max => InstructionType::Numeric,
F64Copysign => InstructionType::Numeric,
F32Abs => InstructionType::Float,
F32Neg => InstructionType::Float,
F32Ceil => InstructionType::Float,
F32Floor => InstructionType::Float,
F32Trunc => InstructionType::Float,
F32Nearest => InstructionType::Float,
F32Sqrt => InstructionType::Float,
F32Add => InstructionType::Float,
F32Sub => InstructionType::Float,
F32Mul => InstructionType::Float,
F32Div => InstructionType::Float,
F32Min => InstructionType::Float,
F32Max => InstructionType::Float,
F32Copysign => InstructionType::Float,
F64Abs => InstructionType::Float,
F64Neg => InstructionType::Float,
F64Ceil => InstructionType::Float,
F64Floor => InstructionType::Float,
F64Trunc => InstructionType::Float,
F64Nearest => InstructionType::Float,
F64Sqrt => InstructionType::Float,
F64Add => InstructionType::Float,
F64Sub => InstructionType::Float,
F64Mul => InstructionType::Float,
F64Div => InstructionType::Float,
F64Min => InstructionType::Float,
F64Max => InstructionType::Float,
F64Copysign => InstructionType::Float,
I32WrapI64 => InstructionType::Conversion,
I32TruncSF32 => InstructionType::Conversion,
I32TruncUF32 => InstructionType::Conversion,
I32TruncSF64 => InstructionType::Conversion,
I32TruncUF64 => InstructionType::Conversion,
I64ExtendSI32 => InstructionType::Conversion,
I64ExtendUI32 => InstructionType::Conversion,
I64TruncSF32 => InstructionType::Conversion,
I64TruncUF32 => InstructionType::Conversion,
I64TruncSF64 => InstructionType::Conversion,
I64TruncUF64 => InstructionType::Conversion,
F32ConvertSI32 => InstructionType::Conversion,
F32ConvertUI32 => InstructionType::Conversion,
F32ConvertSI64 => InstructionType::Conversion,
F32ConvertUI64 => InstructionType::Conversion,
F32DemoteF64 => InstructionType::Conversion,
F64ConvertSI32 => InstructionType::Conversion,
F64ConvertUI32 => InstructionType::Conversion,
F64ConvertSI64 => InstructionType::Conversion,
F64ConvertUI64 => InstructionType::Conversion,
F64PromoteF32 => InstructionType::Conversion,
I32TruncSF32 => InstructionType::FloatConversion,
I32TruncUF32 => InstructionType::FloatConversion,
I32TruncSF64 => InstructionType::FloatConversion,
I32TruncUF64 => InstructionType::FloatConversion,
I64TruncSF32 => InstructionType::FloatConversion,
I64TruncUF32 => InstructionType::FloatConversion,
I64TruncSF64 => InstructionType::FloatConversion,
I64TruncUF64 => InstructionType::FloatConversion,
F32ConvertSI32 => InstructionType::FloatConversion,
F32ConvertUI32 => InstructionType::FloatConversion,
F32ConvertSI64 => InstructionType::FloatConversion,
F32ConvertUI64 => InstructionType::FloatConversion,
F32DemoteF64 => InstructionType::FloatConversion,
F64ConvertSI32 => InstructionType::FloatConversion,
F64ConvertUI32 => InstructionType::FloatConversion,
F64ConvertSI64 => InstructionType::FloatConversion,
F64ConvertUI64 => InstructionType::FloatConversion,
F64PromoteF32 => InstructionType::FloatConversion,
I32ReinterpretF32 => InstructionType::Reinterpretation,
I64ReinterpretF64 => InstructionType::Reinterpretation,
@@ -250,19 +262,34 @@ impl InstructionType {
}
}
#[derive(Debug, Default)]
#[derive(Debug)]
pub struct Set {
entries: HashMap<InstructionType, u32>,
regular: u32,
entries: HashMap<InstructionType, Metering>,
grow: u32,
}
impl Default for Set {
fn default() -> Self {
Set {
regular: 1,
entries: HashMap::new(),
grow: 0,
}
}
}
impl Set {
pub fn new(entries: HashMap<InstructionType, u32>) -> Self {
Set { entries: entries, grow: 0, }
pub fn new(regular: u32, entries: HashMap<InstructionType, Metering>) -> Self {
Set { regular: regular, entries: entries, grow: 0, }
}
pub fn process(&self, opcode: &elements::Opcode) -> u32 {
self.entries.get(&InstructionType::op(opcode)).map(|x| *x).unwrap_or(1)
pub fn process(&self, opcode: &elements::Opcode) -> Result<u32, ()> {
match self.entries.get(&InstructionType::op(opcode)).map(|x| *x) {
None | Some(Metering::Regular) => Ok(self.regular),
Some(Metering::Forbidden) => Err(()),
Some(Metering::Fixed(val)) => Ok(val),
}
}
pub fn grow_cost(&self) -> u32 {
@@ -273,4 +300,12 @@ impl Set {
self.grow = val;
self
}
pub fn with_forbidden_floats(mut self) -> Self {
self.entries.insert(InstructionType::Float, Metering::Forbidden);
self.entries.insert(InstructionType::FloatComparsion, Metering::Forbidden);
self.entries.insert(InstructionType::FloatConst, Metering::Forbidden);
self.entries.insert(InstructionType::FloatConversion, Metering::Forbidden);
self
}
}