From 5f43b7722ccb847795eb6676da07e32412ec5e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Magnenat?= Date: Tue, 5 Jan 2021 20:31:57 +0100 Subject: [PATCH] Removed duplicated code in vm.run using macros. --- boa/src/vm/mod.rs | 163 ++++++++++++++-------------------------------- 1 file changed, 48 insertions(+), 115 deletions(-) diff --git a/boa/src/vm/mod.rs b/boa/src/vm/mod.rs index ac73339acf8..19fe493c6a2 100644 --- a/boa/src/vm/mod.rs +++ b/boa/src/vm/mod.rs @@ -51,162 +51,96 @@ impl<'a> VM<'a> { while idx < self.instructions.len() { let _timer = BoaProfiler::global().start_event(&self.instructions[idx].to_string(), "vm"); - match self.instructions[idx] { - Instruction::Undefined => self.push(Value::undefined()), - Instruction::Null => self.push(Value::null()), - Instruction::True => self.push(Value::boolean(true)), - Instruction::False => self.push(Value::boolean(false)), - Instruction::Zero => self.push(Value::integer(0)), - Instruction::One => self.push(Value::integer(1)), - Instruction::Int32(i) => self.push(Value::integer(i)), - Instruction::Rational(r) => self.push(Value::rational(r)), + macro_rules! binop { + ($e:ident) => {{ + let r = self.pop(); + let l = self.pop(); + let val = l.$e(&r, self.ctx)?; + val.into() + }} + } + let result = match self.instructions[idx] { + Instruction::Undefined => Value::undefined(), + Instruction::Null => Value::null(), + Instruction::True => Value::boolean(true), + Instruction::False => Value::boolean(false), + Instruction::Zero => Value::integer(0), + Instruction::One => Value::integer(1), + Instruction::Int32(i) => Value::integer(i), + Instruction::Rational(r) => Value::rational(r), Instruction::String(index) => { - let value = self.pool[index].clone(); - self.push(value) + self.pool[index].clone() } Instruction::BigInt(index) => { - let value = self.pool[index].clone(); - self.push(value) + self.pool[index].clone() } Instruction::Add => { - let r = self.pop(); - let l = self.pop(); - let val = l.add(&r, self.ctx)?; - - self.push(val); + binop!(add) } Instruction::Sub => { - let r = self.pop(); - let l = self.pop(); - let val = l.sub(&r, self.ctx)?; - - self.push(val); + binop!(sub) } Instruction::Mul => { - let r = self.pop(); - let l = self.pop(); - let val = l.mul(&r, self.ctx)?; - - self.push(val); + binop!(mul) } Instruction::Div => { - let r = self.pop(); - let l = self.pop(); - let val = l.div(&r, self.ctx)?; - - self.push(val); + binop!(div) } Instruction::Pow => { - let r = self.pop(); - let l = self.pop(); - let val = l.pow(&r, self.ctx)?; - - self.push(val); + binop!(pow) } Instruction::Mod => { - let r = self.pop(); - let l = self.pop(); - let val = l.rem(&r, self.ctx)?; - - self.push(val); + binop!(rem) } Instruction::BitAnd => { - let r = self.pop(); - let l = self.pop(); - let val = l.bitand(&r, self.ctx)?; - - self.push(val); + binop!(bitand) } Instruction::BitOr => { - let r = self.pop(); - let l = self.pop(); - let val = l.bitor(&r, self.ctx)?; - - self.push(val); + binop!(bitor) } Instruction::BitXor => { - let r = self.pop(); - let l = self.pop(); - let val = l.bitxor(&r, self.ctx)?; - - self.push(val); + binop!(bitxor) } Instruction::Shl => { - let r = self.pop(); - let l = self.pop(); - let val = l.shl(&r, self.ctx)?; - - self.push(val); + binop!(shl) } Instruction::Shr => { - let r = self.pop(); - let l = self.pop(); - let val = l.shr(&r, self.ctx)?; - - self.push(val); + binop!(shr) } Instruction::UShr => { - let r = self.pop(); - let l = self.pop(); - let val = l.ushr(&r, self.ctx)?; - - self.push(val); + binop!(ushr) } Instruction::Eq => { let r = self.pop(); let l = self.pop(); - let val = l.equals(&r, self.ctx)?; - - self.push(val.into()); + (l.equals(&r, self.ctx)?).into() } Instruction::NotEq => { let r = self.pop(); let l = self.pop(); - let val = !l.equals(&r, self.ctx)?; - - self.push(val.into()); + (!l.equals(&r, self.ctx)?).into() } Instruction::StrictEq => { let r = self.pop(); let l = self.pop(); - let val = l.strict_equals(&r); - - self.push(val.into()); + (l.strict_equals(&r)).into() } Instruction::StrictNotEq => { let r = self.pop(); let l = self.pop(); - let val = !l.strict_equals(&r); - - self.push(val.into()); + (!l.strict_equals(&r)).into() } Instruction::Gt => { - let r = self.pop(); - let l = self.pop(); - let val = l.ge(&r, self.ctx)?; - - self.push(val.into()); + binop!(gt) } Instruction::Ge => { - let r = self.pop(); - let l = self.pop(); - let val = l.ge(&r, self.ctx)?; - - self.push(val.into()); + binop!(ge) } Instruction::Lt => { - let r = self.pop(); - let l = self.pop(); - let val = l.lt(&r, self.ctx)?; - - self.push(val.into()); + binop!(lt) } Instruction::Le => { - let r = self.pop(); - let l = self.pop(); - let val = l.le(&r, self.ctx)?; - - self.push(val.into()); + binop!(le) } Instruction::In => { let r = self.pop(); @@ -219,9 +153,7 @@ impl<'a> VM<'a> { )); } let key = l.to_property_key(self.ctx)?; - let val = self.ctx.has_property(&r, &key); - - self.push(val.into()); + self.ctx.has_property(&r, &key).into() } Instruction::InstanceOf => { let r = self.pop(); @@ -238,24 +170,24 @@ impl<'a> VM<'a> { } Instruction::Void => { let _value = self.pop(); - self.push(Value::undefined()); + Value::undefined() } Instruction::TypeOf => { let value = self.pop(); - self.push(value.get_type().as_str().into()); + value.get_type().as_str().into() } Instruction::Pos => { let value = self.pop(); let value = value.to_number(self.ctx)?; - self.push(value.into()); + value.into() } Instruction::Neg => { let value = self.pop(); - self.push(Value::from(!value.to_boolean())); + Value::from(!value.to_boolean()) } Instruction::Not => { let value = self.pop(); - self.push((!value.to_boolean()).into()); + (!value.to_boolean()).into() } Instruction::BitNot => { let target = self.pop(); @@ -266,9 +198,10 @@ impl<'a> VM<'a> { // TODO: this is not spec compliant. !(num as i32) }; - self.push(value.into()); + value.into() } - } + }; + self.push(result); idx += 1; }