Skip to content

Commit

Permalink
More changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Razican committed May 13, 2020
1 parent 948532b commit fe83bf3
Show file tree
Hide file tree
Showing 70 changed files with 1,667 additions and 1,053 deletions.
23 changes: 15 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion boa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ exclude = ["../.vscode/*", "../Dockerfile", "../Makefile", "../.editorConfig"]
edition = "2018"

[dependencies]
gc = { version = "0.3.4", features = ["derive"], git = "https://github.com/Razican/rust-gc.git", branch = "box_str" }
gc = { version = "0.3.4", features = ["derive"], git = "https://github.com/Manishearth/rust-gc.git" }
serde_json = "1.0.53"
rand = "0.7.3"
num-traits = "0.2.11"
Expand All @@ -20,6 +20,7 @@ rustc-hash = "1.1.0"

# Optional Dependencies
serde = { version = "1.0.110", features = ["derive"], optional = true }
once_cell = "1.3.1"

[dev-dependencies]
criterion = "0.3.2"
Expand Down
12 changes: 6 additions & 6 deletions boa/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use crate::{
value::{ResultValue, Value},
},
environment::lexical_environment::{new_function_environment, Environment},
exec::Interpreter,
syntax::ast::node::{FormalParameter, Node},
exec::{Executable, Interpreter},
syntax::ast::node::{FormalParameter, StatementList},
};
use gc::{unsafe_empty_trace, Finalize, Trace};
use std::fmt::{self, Debug};
Expand Down Expand Up @@ -48,14 +48,14 @@ pub enum ThisMode {
#[derive(Clone, Finalize)]
pub enum FunctionBody {
BuiltIn(NativeFunctionData),
Ordinary(Node),
Ordinary(StatementList),
}

impl Debug for FunctionBody {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::BuiltIn(_) => write!(f, "native code"),
Self::Ordinary(node) => write!(f, "{}", node),
Self::Ordinary(statements) => write!(f, "{:?}", statements),
}
}
}
Expand Down Expand Up @@ -191,7 +191,7 @@ impl Function {

// Call body should be set before reaching here
let result = match &self.body {
FunctionBody::Ordinary(ref body) => interpreter.exec(body),
FunctionBody::Ordinary(ref body) => body.run(interpreter),
_ => panic!("Ordinary function should not have BuiltIn Function body"),
};

Expand Down Expand Up @@ -250,7 +250,7 @@ impl Function {

// Call body should be set before reaching here
let result = match &self.body {
FunctionBody::Ordinary(ref body) => interpreter.exec(body),
FunctionBody::Ordinary(ref body) => body.run(interpreter),
_ => panic!("Ordinary function should not have BuiltIn Function body"),
};

Expand Down
4 changes: 2 additions & 2 deletions boa/src/exec/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ impl Executable for ArrayDecl {
let mut elements = Vec::new();
for elem in self.as_ref() {
if let Node::Spread(ref x) = elem {
let val = interpreter.exec(x)?;
let val = x.run(interpreter)?;
let mut vals = interpreter.extract_array_properties(&val).unwrap();
elements.append(&mut vals);
continue; // Don't push array after spread
}
elements.push(interpreter.exec(&elem)?);
elements.push(elem.run(interpreter)?);
}
add_to_array_object(&array, &elements)?;

Expand Down
6 changes: 3 additions & 3 deletions boa/src/exec/arrow_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ impl Executable for ArrowFunctionDecl {
// .get_field_slice("Prototype");

let func = FunctionObject::create_ordinary(
self.params.clone(), // TODO: args shouldn't need to be a reference it should be passed by value
self.params().to_vec(), // TODO: args shouldn't need to be a reference it should be passed by value
interpreter
.realm_mut()
.environment
.get_current_environment()
.clone(),
FunctionBody::Ordinary(*self.body.clone()),
FunctionBody::Ordinary(self.body().to_vec().into()),
ThisMode::Lexical,
);

let mut new_func = Object::function();
new_func.set_call(func);
let val = Value::from(new_func);
val.set_field_slice("length", Value::from(self.params.len()));
val.set_field_slice("length", Value::from(self.params().len()));

Ok(val)
}
Expand Down
6 changes: 4 additions & 2 deletions boa/src/exec/block.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Block statement execution.
use super::{Executable, Interpreter};
use crate::{
builtins::value::{ResultValue, Value},
Expand All @@ -15,8 +17,8 @@ impl Executable for Block {
}

let mut obj = Value::null();
for statement in self.as_ref() {
obj = interpreter.exec(statement)?;
for statement in self.statements() {
obj = statement.run(interpreter)?;

// early return
if interpreter.is_return {
Expand Down
114 changes: 114 additions & 0 deletions boa/src/exec/declaration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//! Declaration execution.
use super::{Executable, Interpreter};
use crate::{
builtins::{
function::{Function as FunctionObject, FunctionBody, ThisMode},
object::Object,
value::{ResultValue, Value},
},
environment::lexical_environment::VariableScope,
syntax::ast::node::{FunctionDecl, FunctionExpr, VarDeclList},
};

impl Executable for FunctionDecl {
fn run(&self, interpreter: &mut Interpreter) -> ResultValue {
// Todo: Function.prototype doesn't exist yet, so the prototype right now is the Object.prototype
// let proto = &self
// .realm
// .environment
// .get_global_object()
// .expect("Could not get the global object")
// .get_field_slice("Object")
// .get_field_slice("Prototype");

let func = FunctionObject::create_ordinary(
self.parameters().to_vec(),
interpreter
.realm_mut()
.environment
.get_current_environment()
.clone(),
FunctionBody::Ordinary(self.body().to_vec().into()),
ThisMode::NonLexical,
);

let mut new_func = Object::function();
new_func.set_call(func);
let val = Value::from(new_func);
val.set_field_slice("length", Value::from(self.parameters().len()));

// Set the name and assign it in the current environment
if let Some(name) = self.name() {
val.set_field_slice("name", Value::from(self.name()));
interpreter.realm_mut().environment.create_mutable_binding(
name.to_owned(),
false,
VariableScope::Function,
);

interpreter
.realm_mut()
.environment
.initialize_binding(name, val.clone());
}

Ok(val)
}
}

impl Executable for FunctionExpr {
fn run(&self, interpreter: &mut Interpreter) -> ResultValue {
// Todo: Function.prototype doesn't exist yet, so the prototype right now is the Object.prototype
// let proto = &self
// .realm
// .environment
// .get_global_object()
// .expect("Could not get the global object")
// .get_field_slice("Object")
// .get_field_slice("Prototype");

let func = FunctionObject::create_ordinary(
self.parameters().to_vec(),
interpreter
.realm_mut()
.environment
.get_current_environment()
.clone(),
FunctionBody::Ordinary(self.body().to_vec().into()),
ThisMode::NonLexical,
);

let mut new_func = Object::function();
new_func.set_call(func);
let val = Value::from(new_func);
val.set_field_slice("length", Value::from(self.parameters().len()));

if let Some(name) = self.name() {
val.set_field_slice("name", Value::string(name));
}

Ok(val)
}
}

impl Executable for VarDeclList {
fn run(&self, interpreter: &mut Interpreter) -> ResultValue {
for var in self.as_ref() {
let val = match var.init() {
Some(v) => v.run(interpreter)?,
None => Value::undefined(),
};
interpreter.realm_mut().environment.create_mutable_binding(
var.name().to_owned(),
false,
VariableScope::Function,
);
interpreter
.realm_mut()
.environment
.initialize_binding(var.name(), val);
}
Ok(Value::undefined())
}
}
Loading

0 comments on commit fe83bf3

Please sign in to comment.