Browse Source

Refactor exec/expression into exec/call and exec/new (#529)

pull/546/head
croraf 5 years ago committed by GitHub
parent
commit
641dce1357
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 38
      boa/src/exec/call/mod.rs
  2. 7
      boa/src/exec/mod.rs
  3. 39
      boa/src/exec/new/mod.rs

38
boa/src/exec/expression/mod.rs → boa/src/exec/call/mod.rs

@ -1,12 +1,7 @@
//! Expression execution.
use super::{Executable, Interpreter, InterpreterState};
use crate::{
builtins::{
object::{ObjectData, INSTANCE_PROTOTYPE, PROTOTYPE},
value::{ResultValue, Type, Value},
},
syntax::ast::node::{Call, New, Node},
builtins::value::{ResultValue, Type},
syntax::ast::node::{Call, Node},
BoaProfiler,
};
@ -53,32 +48,3 @@ impl Executable for Call {
fnct_result
}
}
impl Executable for New {
fn run(&self, interpreter: &mut Interpreter) -> ResultValue {
// let (callee, args) = match call.as_ref() {
// Node::Call(callee, args) => (callee, args),
// _ => unreachable!("Node::New(ref call): 'call' must only be Node::Call type."),
// };
let func_object = self.expr().run(interpreter)?;
let mut v_args = Vec::with_capacity(self.args().len());
for arg in self.args() {
v_args.push(arg.run(interpreter)?);
}
let this = Value::new_object(None);
// Create a blank object, then set its __proto__ property to the [Constructor].prototype
this.set_internal_slot(INSTANCE_PROTOTYPE, func_object.get_field(PROTOTYPE));
match func_object {
Value::Object(ref obj) => {
let obj = obj.borrow();
if let ObjectData::Function(ref func) = obj.data {
return func.construct(func_object.clone(), &this, &v_args, interpreter);
}
interpreter.throw_type_error("not a constructor")
}
_ => Ok(Value::undefined()),
}
}
}

7
boa/src/exec/mod.rs

@ -3,13 +3,14 @@
mod array;
mod block;
mod break_node;
mod call;
mod conditional;
mod declaration;
mod exception;
mod expression;
mod field;
mod identifier;
mod iteration;
mod new;
mod object;
mod operator;
mod return_smt;
@ -630,7 +631,7 @@ impl Executable for Node {
Node::Identifier(ref identifier) => identifier.run(interpreter),
Node::GetConstField(ref get_const_field_node) => get_const_field_node.run(interpreter),
Node::GetField(ref get_field) => get_field.run(interpreter),
Node::Call(ref expr) => expr.run(interpreter),
Node::Call(ref call) => call.run(interpreter),
Node::WhileLoop(ref while_loop) => while_loop.run(interpreter),
Node::DoWhileLoop(ref do_while) => do_while.run(interpreter),
Node::ForLoop(ref for_loop) => for_loop.run(interpreter),
@ -641,7 +642,7 @@ impl Executable for Node {
// <https://tc39.es/ecma262/#sec-createdynamicfunction>
Node::FunctionDecl(ref decl) => decl.run(interpreter),
// <https://tc39.es/ecma262/#sec-createdynamicfunction>
Node::FunctionExpr(ref expr) => expr.run(interpreter),
Node::FunctionExpr(ref function_expr) => function_expr.run(interpreter),
Node::ArrowFunctionDecl(ref decl) => decl.run(interpreter),
Node::BinOp(ref op) => op.run(interpreter),
Node::UnaryOp(ref op) => op.run(interpreter),

39
boa/src/exec/new/mod.rs

@ -0,0 +1,39 @@
use super::{Executable, Interpreter};
use crate::{
builtins::{
object::{ObjectData, INSTANCE_PROTOTYPE, PROTOTYPE},
value::{ResultValue, Value},
},
syntax::ast::node::New,
BoaProfiler,
};
impl Executable for New {
fn run(&self, interpreter: &mut Interpreter) -> ResultValue {
let _timer = BoaProfiler::global().start_event("New", "exec");
// let (callee, args) = match call.as_ref() {
// Node::Call(callee, args) => (callee, args),
// _ => unreachable!("Node::New(ref call): 'call' must only be Node::Call type."),
// };
let func_object = self.expr().run(interpreter)?;
let mut v_args = Vec::with_capacity(self.args().len());
for arg in self.args() {
v_args.push(arg.run(interpreter)?);
}
let this = Value::new_object(None);
// Create a blank object, then set its __proto__ property to the [Constructor].prototype
this.set_internal_slot(INSTANCE_PROTOTYPE, func_object.get_field(PROTOTYPE));
match func_object {
Value::Object(ref obj) => {
let obj = obj.borrow();
if let ObjectData::Function(ref func) = obj.data {
return func.construct(func_object.clone(), &this, &v_args, interpreter);
}
interpreter.throw_type_error("not a constructor")
}
_ => Ok(Value::undefined()),
}
}
}
Loading…
Cancel
Save