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 Feb 17, 2021
1 parent a2e5dca commit 4de4d4a
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 119 deletions.
174 changes: 56 additions & 118 deletions boa/src/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,162 +78,93 @@ impl<'a> VM<'a> {

let _timer =
BoaProfiler::global().start_event(&self.instructions[self.idx].to_string(), "vm");
match self.instructions[self.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)?;
Some(val.into())
}};
}
let result = match self.instructions[self.idx] {
Instruction::Undefined => Some(Value::undefined()),
Instruction::Null => Some(Value::null()),
Instruction::True => Some(Value::boolean(true)),
Instruction::False => Some(Value::boolean(false)),
Instruction::Zero => Some(Value::integer(0)),
Instruction::One => Some(Value::integer(1)),
Instruction::Int32(i) => Some(Value::integer(i)),
Instruction::Rational(r) => Some(Value::rational(r)),
Instruction::String(index) => Some(self.pool[index].clone()),
Instruction::BigInt(index) => Some(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());
Some((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());
Some((!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());
Some((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());
Some((!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 @@ -246,9 +177,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());
Some(self.ctx.has_property(&r, &key).into())
}
Instruction::InstanceOf => {
let r = self.pop();
Expand All @@ -265,24 +194,24 @@ impl<'a> VM<'a> {
}
Instruction::Void => {
let _value = self.pop();
self.push(Value::undefined());
Some(Value::undefined())
}
Instruction::TypeOf => {
let value = self.pop();
self.push(value.get_type().as_str().into());
Some(value.get_type().as_str().into())
}
Instruction::Pos => {
let value = self.pop();
let value = value.to_number(self.ctx)?;
self.push(value.into());
Some(value.into())
}
Instruction::Neg => {
let value = self.pop();
self.push(Value::from(!value.to_boolean()));
Some(Value::from(!value.to_boolean()))
}
Instruction::Not => {
let value = self.pop();
self.push((!value.to_boolean()).into());
Some((!value.to_boolean()).into())
}
Instruction::BitNot => {
let target = self.pop();
Expand All @@ -293,7 +222,7 @@ impl<'a> VM<'a> {
// TODO: this is not spec compliant.
!(num as i32)
};
self.push(value.into());
Some(value.into())
}
Instruction::DefVar(name_index) => {
let name: String = self.pool[name_index].to_string(self.ctx)?.to_string();
Expand All @@ -303,6 +232,8 @@ impl<'a> VM<'a> {
.environment
.create_mutable_binding(name.to_string(), false, VariableScope::Function)
.map_err(|e| e.to_error(self.ctx))?;

None
}
Instruction::DefLet(name_index) => {
let name = self.pool[name_index].to_string(self.ctx)?;
Expand All @@ -312,6 +243,8 @@ impl<'a> VM<'a> {
.environment
.create_mutable_binding(name.to_string(), false, VariableScope::Block)
.map_err(|e| e.to_error(self.ctx))?;

None
}
Instruction::DefConst(name_index) => {
let name = self.pool[name_index].to_string(self.ctx)?;
Expand All @@ -321,6 +254,8 @@ impl<'a> VM<'a> {
.environment
.create_immutable_binding(name.to_string(), false, VariableScope::Block)
.map_err(|e| e.to_error(self.ctx))?;

None
}
Instruction::InitLexical(name_index) => {
let name = self.pool[name_index].to_string(self.ctx)?;
Expand All @@ -331,8 +266,11 @@ impl<'a> VM<'a> {
.initialize_binding(&name, value.clone())
.map_err(|e| e.to_error(self.ctx))?;

self.push(value);
Some(value)
}
};
if let Some(value) = result {
self.push(value);
}

self.idx += 1;
Expand Down

0 comments on commit 4de4d4a

Please sign in to comment.