Skip to content

Commit

Permalink
Removed duplicated code in vm.run using macros.
Browse files Browse the repository at this point in the history
  • Loading branch information
stephanemagnenat committed Jan 6, 2021
1 parent 0e41be1 commit 4e69075
Showing 1 changed file with 47 additions and 118 deletions.
165 changes: 47 additions & 118 deletions boa/src/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,162 +51,92 @@ 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)),
Instruction::String(index) => {
let value = self.pool[index].clone();
self.push(value)
}
Instruction::BigInt(index) => {
let value = self.pool[index].clone();
self.push(value)
}
Instruction::Add => {
macro_rules! binop {
($e:ident) => {{
let r = self.pop();
let l = self.pop();
let val = l.add(&r, self.ctx)?;

self.push(val);
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) => self.pool[index].clone(),
Instruction::BigInt(index) => self.pool[index].clone(),
Instruction::Add => {
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();
Expand All @@ -219,9 +149,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();
Expand All @@ -238,24 +166,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();
Expand All @@ -266,9 +194,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;
}
Expand Down

0 comments on commit 4e69075

Please sign in to comment.