Skip to content

Commit

Permalink
Removed the Interpreter::exec() method
Browse files Browse the repository at this point in the history
  • Loading branch information
Razican committed May 21, 2020
1 parent 462bf9a commit ffabf6a
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 46 deletions.
2 changes: 1 addition & 1 deletion boa/src/exec/iteration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl Executable for ForLoop {
}

if let Some(init) = self.init() {
interpreter.exec(init)?;
init.run(interpreter)?;
}

while self
Expand Down
73 changes: 33 additions & 40 deletions boa/src/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,6 @@ impl Interpreter {
&mut self.realm
}

/// Run an expression.
pub(crate) fn exec(&mut self, node: &Node) -> ResultValue {
node.run(self)
}

/// <https://tc39.es/ecma262/#sec-call>
pub(crate) fn call(
&mut self,
Expand Down Expand Up @@ -360,10 +355,10 @@ impl Interpreter {
Ok(value)
}
Node::GetConstField(ref obj, ref field) => {
Ok(self.exec(obj)?.set_field_slice(field, value))
Ok(obj.run(self)?.set_field_slice(field, value))
}
Node::GetField(ref obj, ref field) => {
Ok(self.exec(obj)?.set_field(self.exec(field)?, value))
Ok(obj.run(self)?.set_field(field.run(self)?, value))
}
_ => panic!("TypeError: invalid assignment to {}", node),
}
Expand Down Expand Up @@ -392,20 +387,20 @@ impl Executable for Node {
Ok(val)
}
Node::GetConstField(ref obj, ref field) => {
let val_obj = interpreter.exec(obj)?;
let val_obj = obj.run(interpreter)?;
Ok(val_obj.borrow().get_field_slice(field))
}
Node::GetField(ref obj, ref field) => {
let val_obj = interpreter.exec(obj)?;
let val_field = interpreter.exec(field)?;
let val_obj = obj.run(interpreter)?;
let val_field = field.run(interpreter)?;
Ok(val_obj
.borrow()
.get_field_slice(&val_field.borrow().to_string()))
}
Node::Call(ref callee, ref args) => {
let (mut this, func) = match callee.deref() {
Node::GetConstField(ref obj, ref field) => {
let mut obj = interpreter.exec(obj)?;
let mut obj = obj.run(interpreter)?;
if obj.get_type() != "object" || obj.get_type() != "symbol" {
obj = interpreter
.to_object(&obj)
Expand All @@ -414,27 +409,27 @@ impl Executable for Node {
(obj.clone(), obj.borrow().get_field_slice(field))
}
Node::GetField(ref obj, ref field) => {
let obj = interpreter.exec(obj)?;
let field = interpreter.exec(field)?;
let obj = obj.run(interpreter)?;
let field = field.run(interpreter)?;
(
obj.clone(),
obj.borrow().get_field_slice(&field.borrow().to_string()),
)
}
_ => (
interpreter.realm().global_obj.clone(),
interpreter.exec(&callee.clone())?,
callee.run(interpreter)?,
), // 'this' binding should come from the function's self-contained environment
};
let mut v_args = Vec::with_capacity(args.len());
for arg in args.iter() {
if let Node::Spread(ref x) = arg.deref() {
let val = interpreter.exec(x)?;
let val = x.run(interpreter)?;
let mut vals = interpreter.extract_array_properties(&val).unwrap();
v_args.append(&mut vals);
break; // after spread we don't accept any new arguments
}
v_args.push(interpreter.exec(arg)?);
v_args.push(arg.run(interpreter)?);
}

// execute the function call itself
Expand All @@ -447,35 +442,35 @@ impl Executable for Node {
}
Node::WhileLoop(ref cond, ref expr) => {
let mut result = Value::undefined();
while interpreter.exec(cond)?.borrow().is_true() {
result = interpreter.exec(expr)?;
while cond.run(interpreter)?.borrow().is_true() {
result = expr.run(interpreter)?;
}
Ok(result)
}
Node::DoWhileLoop(ref body, ref cond) => {
let mut result = interpreter.exec(body)?;
while interpreter.exec(cond)?.borrow().is_true() {
result = interpreter.exec(body)?;
let mut result = body.run(interpreter)?;
while cond.run(interpreter)?.borrow().is_true() {
result = body.run(interpreter)?;
}
Ok(result)
}
Node::ForLoop(ref for_loop) => for_loop.run(interpreter),
Node::If(ref cond, ref expr, None) => {
Ok(if interpreter.exec(cond)?.borrow().is_true() {
interpreter.exec(expr)?
Ok(if cond.run(interpreter)?.borrow().is_true() {
expr.run(interpreter)?
} else {
Value::undefined()
})
}
Node::If(ref cond, ref expr, Some(ref else_e)) => {
Ok(if interpreter.exec(cond)?.borrow().is_true() {
interpreter.exec(expr)?
Ok(if cond.run(interpreter)?.borrow().is_true() {
expr.run(interpreter)?
} else {
interpreter.exec(else_e)?
else_e.run(interpreter)?
})
}
Node::Switch(ref val_e, ref vals, ref default) => {
let val = interpreter.exec(val_e)?;
let val = val_e.run(interpreter)?;
let mut result = Value::null();
let mut matched = false;
for tup in vals.iter() {
Expand All @@ -485,19 +480,17 @@ impl Executable for Node {
matched = true;
let last_expr = block.last().expect("Block has no expressions");
for expr in block.iter() {
let e_result = interpreter.exec(expr)?;
let e_result = expr.run(interpreter)?;
if expr == last_expr {
result = e_result;
}
}
}
}
if !matched && default.is_some() {
result = interpreter.exec(
default
.as_ref()
.expect("Could not get default as reference"),
)?;
if !matched {
if let Some(default) = default {
result = default.run(interpreter)?;
}
}
Ok(result)
}
Expand All @@ -514,7 +507,7 @@ impl Executable for Node {
match property {
PropertyDefinition::Property(key, value) => {
obj.borrow()
.set_field_slice(&key.clone(), interpreter.exec(value)?);
.set_field_slice(&key.clone(), value.run(interpreter)?);
}
PropertyDefinition::MethodDefinition(kind, name, func) => {
if let MethodDefinitionKind::Ordinary = kind {
Expand Down Expand Up @@ -545,10 +538,10 @@ impl Executable for Node {
_ => unreachable!("Node::New(ref call): 'call' must only be Node::Call type."),
};

let func_object = interpreter.exec(callee)?;
let func_object = callee.run(interpreter)?;
let mut v_args = Vec::with_capacity(args.len());
for arg in args.iter() {
v_args.push(interpreter.exec(arg)?);
v_args.push(arg.run(interpreter)?);
}
let mut this = Value::new_object(None);
// Create a blank object, then set its __proto__ property to the [Constructor].prototype
Expand All @@ -568,21 +561,21 @@ impl Executable for Node {
}
Node::Return(ref ret) => {
let result = match *ret {
Some(ref v) => interpreter.exec(v),
Some(ref v) => v.run(interpreter),
None => Ok(Value::undefined()),
};
// Set flag for return
interpreter.is_return = true;
result
}
Node::Throw(ref ex) => Err(interpreter.exec(ex)?),
Node::Throw(ref ex) => Err(ex.run(interpreter)?),
Node::Assign(ref op) => op.run(interpreter),
Node::VarDeclList(ref decl) => decl.run(interpreter),
Node::LetDeclList(ref decl) => decl.run(interpreter),
Node::ConstDeclList(ref decl) => decl.run(interpreter),
Node::Spread(ref node) => {
// TODO: for now we can do nothing but return the value as-is
interpreter.exec(node)
node.run(interpreter)
}
Node::This => {
// Will either return `this` binding or undefined
Expand Down
7 changes: 3 additions & 4 deletions boa/src/exec/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,11 @@ impl Executable for UnaryOp {
op::UnaryOp::Void => Value::undefined(),
op::UnaryOp::Delete => match *self.target() {
Node::GetConstField(ref obj, ref field) => {
Value::boolean(interpreter.exec(obj)?.remove_property(field))
Value::boolean(obj.run(interpreter)?.remove_property(field))
}
Node::GetField(ref obj, ref field) => Value::boolean(
interpreter
.exec(obj)?
.remove_property(&interpreter.exec(field)?.to_string()),
obj.run(interpreter)?
.remove_property(&field.run(interpreter)?.to_string()),
),
Node::Identifier(_) => Value::boolean(false),
Node::ArrayDecl(_)
Expand Down
2 changes: 1 addition & 1 deletion boa/src/exec/statement_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ impl Executable for StatementList {
fn run(&self, interpreter: &mut Interpreter) -> ResultValue {
let mut obj = Value::null();
for (i, item) in self.statements().iter().enumerate() {
let val = interpreter.exec(item)?;
let val = item.run(interpreter)?;
// early return
if interpreter.is_return {
obj = val;
Expand Down

0 comments on commit ffabf6a

Please sign in to comment.