Skip to content

Commit

Permalink
Initial implementation of Map() (boa-dev#550)
Browse files Browse the repository at this point in the history
Co-authored-by: HalidOdat <[email protected]>
  • Loading branch information
2 people authored and graham committed Jul 17, 2020
1 parent 04ab2f2 commit a1057c5
Show file tree
Hide file tree
Showing 22 changed files with 878 additions and 38 deletions.
14 changes: 12 additions & 2 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions boa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ rustc-hash = "1.1.0"
num-bigint = { version = "0.3.0", features = ["serde"] }
num-integer = "0.1.43"
bitflags = "1.2.1"
indexmap = "1.4.0"
ryu-js = "0.2.0"

# Optional Dependencies
Expand Down
1 change: 1 addition & 0 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,7 @@ impl Array {
global,
prototype,
true,
true,
);

// Static Methods
Expand Down
1 change: 1 addition & 0 deletions boa/src/builtins/bigint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ impl BigInt {
global,
prototype,
false,
true,
);

make_builtin_fn(Self::as_int_n, "asIntN", &bigint_object, 2);
Expand Down
1 change: 1 addition & 0 deletions boa/src/builtins/boolean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ impl Boolean {
global,
prototype,
true,
true,
);

(Self::NAME, boolean_object)
Expand Down
1 change: 1 addition & 0 deletions boa/src/builtins/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ impl Error {
global,
prototype,
true,
true,
);

(Self::NAME, error_object)
Expand Down
1 change: 1 addition & 0 deletions boa/src/builtins/error/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ impl RangeError {
global,
prototype,
true,
true,
);

(Self::NAME, range_error_object)
Expand Down
1 change: 1 addition & 0 deletions boa/src/builtins/error/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ impl ReferenceError {
global,
prototype,
true,
true,
);

(Self::NAME, reference_error_object)
Expand Down
1 change: 1 addition & 0 deletions boa/src/builtins/error/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ impl SyntaxError {
global,
prototype,
true,
true,
);

(Self::NAME, syntax_error_object)
Expand Down
1 change: 1 addition & 0 deletions boa/src/builtins/error/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl TypeError {
global,
prototype,
true,
true,
);

(Self::NAME, type_error_object)
Expand Down
60 changes: 48 additions & 12 deletions boa/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use crate::{
syntax::ast::node::{FormalParameter, StatementList},
BoaProfiler,
};
use bitflags::bitflags;
use gc::{unsafe_empty_trace, Finalize, Trace};
use std::fmt::{self, Debug};

Expand Down Expand Up @@ -90,6 +91,43 @@ unsafe impl Trace for FunctionBody {
unsafe_empty_trace!();
}

bitflags! {
#[derive(Finalize, Default)]
struct FunctionFlags: u8 {
const CALLABLE = 0b0000_0001;
const CONSTRUCTABLE = 0b0000_0010;
}
}

impl FunctionFlags {
fn from_parameters(callable: bool, constructable: bool) -> Self {
let mut flags = Self::default();

if callable {
flags |= Self::CALLABLE;
}
if constructable {
flags |= Self::CONSTRUCTABLE;
}

flags
}

#[inline]
fn is_callable(&self) -> bool {
self.contains(Self::CALLABLE)
}

#[inline]
fn is_constructable(&self) -> bool {
self.contains(Self::CONSTRUCTABLE)
}
}

unsafe impl Trace for FunctionFlags {
unsafe_empty_trace!();
}

/// Boa representation of a Function Object.
///
/// <https://tc39.es/ecma262/#sec-ecmascript-function-objects>
Expand All @@ -103,10 +141,8 @@ pub struct Function {
pub this_mode: ThisMode,
// Environment, built-in functions don't need Environments
pub environment: Option<Environment>,
/// Is it constructable
constructable: bool,
/// Is it callable.
callable: bool,
/// Is it constructable or
flags: FunctionFlags,
}

impl Function {
Expand All @@ -126,8 +162,7 @@ impl Function {
environment: scope,
params: parameter_list.into(),
this_mode,
constructable,
callable,
flags: FunctionFlags::from_parameters(callable, constructable),
}
}

Expand Down Expand Up @@ -183,7 +218,7 @@ impl Function {
interpreter: &mut Interpreter,
) -> ResultValue {
let _timer = BoaProfiler::global().start_event("function::call", "function");
if self.callable {
if self.flags.is_callable() {
match self.body {
FunctionBody::BuiltIn(func) => func(this, args_list, interpreter),
FunctionBody::Ordinary(ref body) => {
Expand Down Expand Up @@ -249,7 +284,7 @@ impl Function {
args_list: &[Value],
interpreter: &mut Interpreter,
) -> ResultValue {
if self.constructable {
if self.flags.is_constructable() {
match self.body {
FunctionBody::BuiltIn(func) => {
func(this, args_list, interpreter)?;
Expand Down Expand Up @@ -351,12 +386,12 @@ impl Function {

/// Returns true if the function object is callable.
pub fn is_callable(&self) -> bool {
self.callable
self.flags.is_callable()
}

/// Returns true if the function object is constructable.
pub fn is_constructable(&self) -> bool {
self.constructable
self.flags.is_constructable()
}
}

Expand Down Expand Up @@ -420,13 +455,14 @@ pub fn make_constructor_fn(
global: &Value,
prototype: Value,
constructable: bool,
callable: bool,
) -> Value {
let _timer =
BoaProfiler::global().start_event(&format!("make_constructor_fn: {}", name), "init");

// Create the native function
let mut function = Function::builtin(Vec::new(), body);
function.constructable = constructable;
function.flags = FunctionFlags::from_parameters(callable, constructable);

let mut constructor = Object::function(function);

Expand Down Expand Up @@ -507,7 +543,7 @@ pub fn init(global: &Value) -> (&str, Value) {
let prototype = Value::new_object(Some(global));

let function_object =
make_constructor_fn("Function", 1, make_function, global, prototype, true);
make_constructor_fn("Function", 1, make_function, global, prototype, true, true);

("Function", function_object)
}
Loading

0 comments on commit a1057c5

Please sign in to comment.