Browse Source

Removed duplicated code in vm.run using macros. (#1044)

pull/1162/head
Stéphane Magnenat 4 years ago committed by GitHub
parent
commit
f3f39490ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 174
      boa/src/vm/mod.rs

174
boa/src/vm/mod.rs

@ -78,162 +78,93 @@ impl<'a> VM<'a> {
let _timer = let _timer =
BoaProfiler::global().start_event(&self.instructions[self.idx].to_string(), "vm"); BoaProfiler::global().start_event(&self.instructions[self.idx].to_string(), "vm");
match self.instructions[self.idx] {
Instruction::Undefined => self.push(Value::undefined()), macro_rules! bin_op {
Instruction::Null => self.push(Value::null()), ($op:ident) => {{
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 => {
let r = self.pop(); let r = self.pop();
let l = self.pop(); let l = self.pop();
let val = l.add(&r, self.ctx)?; let val = l.$op(&r, self.ctx)?;
Some(val.into())
self.push(val); }};
}
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 => {
bin_op!(add)
} }
Instruction::Sub => { Instruction::Sub => {
let r = self.pop(); bin_op!(sub)
let l = self.pop();
let val = l.sub(&r, self.ctx)?;
self.push(val);
} }
Instruction::Mul => { Instruction::Mul => {
let r = self.pop(); bin_op!(mul)
let l = self.pop();
let val = l.mul(&r, self.ctx)?;
self.push(val);
} }
Instruction::Div => { Instruction::Div => {
let r = self.pop(); bin_op!(div)
let l = self.pop();
let val = l.div(&r, self.ctx)?;
self.push(val);
} }
Instruction::Pow => { Instruction::Pow => {
let r = self.pop(); bin_op!(pow)
let l = self.pop();
let val = l.pow(&r, self.ctx)?;
self.push(val);
} }
Instruction::Mod => { Instruction::Mod => {
let r = self.pop(); bin_op!(rem)
let l = self.pop();
let val = l.rem(&r, self.ctx)?;
self.push(val);
} }
Instruction::BitAnd => { Instruction::BitAnd => {
let r = self.pop(); bin_op!(bitand)
let l = self.pop();
let val = l.bitand(&r, self.ctx)?;
self.push(val);
} }
Instruction::BitOr => { Instruction::BitOr => {
let r = self.pop(); bin_op!(bitor)
let l = self.pop();
let val = l.bitor(&r, self.ctx)?;
self.push(val);
} }
Instruction::BitXor => { Instruction::BitXor => {
let r = self.pop(); bin_op!(bitxor)
let l = self.pop();
let val = l.bitxor(&r, self.ctx)?;
self.push(val);
} }
Instruction::Shl => { Instruction::Shl => {
let r = self.pop(); bin_op!(shl)
let l = self.pop();
let val = l.shl(&r, self.ctx)?;
self.push(val);
} }
Instruction::Shr => { Instruction::Shr => {
let r = self.pop(); bin_op!(shr)
let l = self.pop();
let val = l.shr(&r, self.ctx)?;
self.push(val);
} }
Instruction::UShr => { Instruction::UShr => {
let r = self.pop(); bin_op!(ushr)
let l = self.pop();
let val = l.ushr(&r, self.ctx)?;
self.push(val);
} }
Instruction::Eq => { Instruction::Eq => {
let r = self.pop(); let r = self.pop();
let l = self.pop(); let l = self.pop();
let val = l.equals(&r, self.ctx)?; Some((l.equals(&r, self.ctx)?).into())
self.push(val.into());
} }
Instruction::NotEq => { Instruction::NotEq => {
let r = self.pop(); let r = self.pop();
let l = self.pop(); let l = self.pop();
let val = !l.equals(&r, self.ctx)?; Some((!l.equals(&r, self.ctx)?).into())
self.push(val.into());
} }
Instruction::StrictEq => { Instruction::StrictEq => {
let r = self.pop(); let r = self.pop();
let l = self.pop(); let l = self.pop();
let val = l.strict_equals(&r); Some((l.strict_equals(&r)).into())
self.push(val.into());
} }
Instruction::StrictNotEq => { Instruction::StrictNotEq => {
let r = self.pop(); let r = self.pop();
let l = self.pop(); let l = self.pop();
let val = !l.strict_equals(&r); Some((!l.strict_equals(&r)).into())
self.push(val.into());
} }
Instruction::Gt => { Instruction::Gt => {
let r = self.pop(); bin_op!(gt)
let l = self.pop();
let val = l.ge(&r, self.ctx)?;
self.push(val.into());
} }
Instruction::Ge => { Instruction::Ge => {
let r = self.pop(); bin_op!(ge)
let l = self.pop();
let val = l.ge(&r, self.ctx)?;
self.push(val.into());
} }
Instruction::Lt => { Instruction::Lt => {
let r = self.pop(); bin_op!(lt)
let l = self.pop();
let val = l.lt(&r, self.ctx)?;
self.push(val.into());
} }
Instruction::Le => { Instruction::Le => {
let r = self.pop(); bin_op!(le)
let l = self.pop();
let val = l.le(&r, self.ctx)?;
self.push(val.into());
} }
Instruction::In => { Instruction::In => {
let r = self.pop(); let r = self.pop();
@ -246,9 +177,7 @@ impl<'a> VM<'a> {
)); ));
} }
let key = l.to_property_key(self.ctx)?; let key = l.to_property_key(self.ctx)?;
let val = self.ctx.has_property(&r, &key); Some(self.ctx.has_property(&r, &key).into())
self.push(val.into());
} }
Instruction::InstanceOf => { Instruction::InstanceOf => {
let r = self.pop(); let r = self.pop();
@ -265,24 +194,24 @@ impl<'a> VM<'a> {
} }
Instruction::Void => { Instruction::Void => {
let _value = self.pop(); let _value = self.pop();
self.push(Value::undefined()); Some(Value::undefined())
} }
Instruction::TypeOf => { Instruction::TypeOf => {
let value = self.pop(); let value = self.pop();
self.push(value.get_type().as_str().into()); Some(value.get_type().as_str().into())
} }
Instruction::Pos => { Instruction::Pos => {
let value = self.pop(); let value = self.pop();
let value = value.to_number(self.ctx)?; let value = value.to_number(self.ctx)?;
self.push(value.into()); Some(value.into())
} }
Instruction::Neg => { Instruction::Neg => {
let value = self.pop(); let value = self.pop();
self.push(Value::from(!value.to_boolean())); Some(Value::from(!value.to_boolean()))
} }
Instruction::Not => { Instruction::Not => {
let value = self.pop(); let value = self.pop();
self.push((!value.to_boolean()).into()); Some((!value.to_boolean()).into())
} }
Instruction::BitNot => { Instruction::BitNot => {
let target = self.pop(); let target = self.pop();
@ -293,7 +222,7 @@ impl<'a> VM<'a> {
// TODO: this is not spec compliant. // TODO: this is not spec compliant.
!(num as i32) !(num as i32)
}; };
self.push(value.into()); Some(value.into())
} }
Instruction::DefVar(name_index) => { Instruction::DefVar(name_index) => {
let name: String = self.pool[name_index].to_string(self.ctx)?.to_string(); let name: String = self.pool[name_index].to_string(self.ctx)?.to_string();
@ -303,6 +232,8 @@ impl<'a> VM<'a> {
.environment .environment
.create_mutable_binding(name.to_string(), false, VariableScope::Function) .create_mutable_binding(name.to_string(), false, VariableScope::Function)
.map_err(|e| e.to_error(self.ctx))?; .map_err(|e| e.to_error(self.ctx))?;
None
} }
Instruction::DefLet(name_index) => { Instruction::DefLet(name_index) => {
let name = self.pool[name_index].to_string(self.ctx)?; let name = self.pool[name_index].to_string(self.ctx)?;
@ -312,6 +243,8 @@ impl<'a> VM<'a> {
.environment .environment
.create_mutable_binding(name.to_string(), false, VariableScope::Block) .create_mutable_binding(name.to_string(), false, VariableScope::Block)
.map_err(|e| e.to_error(self.ctx))?; .map_err(|e| e.to_error(self.ctx))?;
None
} }
Instruction::DefConst(name_index) => { Instruction::DefConst(name_index) => {
let name = self.pool[name_index].to_string(self.ctx)?; let name = self.pool[name_index].to_string(self.ctx)?;
@ -321,6 +254,8 @@ impl<'a> VM<'a> {
.environment .environment
.create_immutable_binding(name.to_string(), false, VariableScope::Block) .create_immutable_binding(name.to_string(), false, VariableScope::Block)
.map_err(|e| e.to_error(self.ctx))?; .map_err(|e| e.to_error(self.ctx))?;
None
} }
Instruction::InitLexical(name_index) => { Instruction::InitLexical(name_index) => {
let name = self.pool[name_index].to_string(self.ctx)?; let name = self.pool[name_index].to_string(self.ctx)?;
@ -331,8 +266,11 @@ impl<'a> VM<'a> {
.initialize_binding(&name, value.clone()) .initialize_binding(&name, value.clone())
.map_err(|e| e.to_error(self.ctx))?; .map_err(|e| e.to_error(self.ctx))?;
self.push(value); Some(value)
} }
};
if let Some(value) = result {
self.push(value);
} }
self.idx += 1; self.idx += 1;

Loading…
Cancel
Save