Skip to content

Commit

Permalink
Merge 7cdbeb7 into f429c16
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Jul 26, 2021
2 parents f429c16 + 7cdbeb7 commit b1f2b95
Show file tree
Hide file tree
Showing 18 changed files with 996 additions and 436 deletions.
2 changes: 0 additions & 2 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,11 @@ impl BuiltIn for Array {
let get_species = FunctionBuilder::new(context, Self::get_species)
.name("get [Symbol.species]")
.constructable(false)
.callable(true)
.build();

let values_function = FunctionBuilder::new(context, Self::values)
.name("values")
.length(0)
.callable(true)
.constructable(false)
.build();

Expand Down
94 changes: 28 additions & 66 deletions boa/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@

use crate::object::PROTOTYPE;
use crate::{
builtins::{Array, BuiltIn},
builtins::BuiltIn,
environment::lexical_environment::Environment,
gc::{empty_trace, Finalize, Trace},
object::{ConstructorBuilder, FunctionBuilder, GcObject, Object, ObjectData},
property::{Attribute, DataDescriptor},
syntax::ast::node::{FormalParameter, RcStatementList},
BoaProfiler, Context, Result, Value,
};
use bitflags::bitflags;

use std::fmt::{self, Debug};

#[cfg(test)]
Expand Down Expand Up @@ -49,75 +49,42 @@ impl Debug for BuiltInFunction {
}
}

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

impl FunctionFlags {
pub(crate) 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]
pub(crate) fn is_callable(&self) -> bool {
self.contains(Self::CALLABLE)
}

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

#[inline]
pub(crate) fn is_lexical_this_mode(&self) -> bool {
self.contains(Self::LEXICAL_THIS_MODE)
}
}

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

/// Boa representation of a Function Object.
///
/// FunctionBody is specific to this interpreter, it will either be Rust code or JavaScript code (AST Node)
///
/// <https://tc39.es/ecma262/#sec-ecmascript-function-objects>
#[derive(Debug, Clone, Finalize, Trace)]
#[derive(Debug, Finalize, Trace)]
pub enum Function {
BuiltIn(BuiltInFunction, FunctionFlags),
BuiltIn {
function: BuiltInFunction,
constructable: bool,
},
Ordinary {
flags: FunctionFlags,
constructable: bool,
lexical_this_mode: bool,
body: RcStatementList,
params: Box<[FormalParameter]>,
environment: Environment,
},
#[cfg(feature = "vm")]
VmOrdinary {
code: gc::Gc<crate::vm::CodeBlock>,
environment: Environment,
},
}

impl Function {
// Adds the final rest parameters to the Environment as an array
#[cfg(not(feature = "vm"))]
pub(crate) fn add_rest_param(
&self,
param: &FormalParameter,
index: usize,
args_list: &[Value],
context: &mut Context,
local_env: &Environment,
) {
use crate::builtins::Array;
// Create array of values
let array = Array::new_array(context);
Array::add_to_array_object(&array, args_list.get(index..).unwrap_or_default(), context)
Expand All @@ -137,7 +104,6 @@ impl Function {

// Adds an argument to the environment
pub(crate) fn add_arguments_to_environment(
&self,
param: &FormalParameter,
value: Value,
local_env: &Environment,
Expand All @@ -154,19 +120,13 @@ impl Function {
.expect("Failed to intialize binding");
}

/// Returns true if the function object is callable.
pub fn is_callable(&self) -> bool {
match self {
Self::BuiltIn(_, flags) => flags.is_callable(),
Self::Ordinary { flags, .. } => flags.is_callable(),
}
}

/// Returns true if the function object is constructable.
pub fn is_constructable(&self) -> bool {
match self {
Self::BuiltIn(_, flags) => flags.is_constructable(),
Self::Ordinary { flags, .. } => flags.is_constructable(),
Self::BuiltIn { constructable, .. } => *constructable,
Self::Ordinary { constructable, .. } => *constructable,
#[cfg(feature = "vm")]
Self::VmOrdinary { code, .. } => code.constructable,
}
}
}
Expand Down Expand Up @@ -230,7 +190,10 @@ pub fn make_builtin_fn<N>(
let _timer = BoaProfiler::global().start_event(&format!("make_builtin_fn: {}", &name), "init");

let mut function = Object::function(
Function::BuiltIn(function.into(), FunctionFlags::CALLABLE),
Function::BuiltIn {
function: function.into(),
constructable: false,
},
interpreter
.standard_objects()
.function_object()
Expand Down Expand Up @@ -270,10 +233,10 @@ impl BuiltInFunctionObject {
.expect("this should be an object")
.set_prototype_instance(prototype.into());

this.set_data(ObjectData::Function(Function::BuiltIn(
BuiltInFunction(|_, _, _| Ok(Value::undefined())),
FunctionFlags::CALLABLE | FunctionFlags::CONSTRUCTABLE,
)));
this.set_data(ObjectData::Function(Function::BuiltIn {
function: BuiltInFunction(|_, _, _| Ok(Value::undefined())),
constructable: true,
}));
Ok(this)
}

Expand Down Expand Up @@ -345,7 +308,6 @@ impl BuiltIn for BuiltInFunctionObject {
FunctionBuilder::new(context, Self::prototype)
.name("")
.length(0)
.callable(true)
.constructable(false)
.build_function_prototype(&function_prototype);

Expand Down
2 changes: 0 additions & 2 deletions boa/src/builtins/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,11 @@ impl BuiltIn for Map {
let get_species = FunctionBuilder::new(context, Self::get_species)
.name("get [Symbol.species]")
.constructable(false)
.callable(true)
.build();

let entries_function = FunctionBuilder::new(context, Self::entries)
.name("entries")
.length(0)
.callable(true)
.constructable(false)
.build();

Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ impl Object {
/// Define a property in an object
pub fn define_property(_: &Value, args: &[Value], context: &mut Context) -> Result<Value> {
let object = args.get(0).cloned().unwrap_or_else(Value::undefined);
if let Some(mut object) = object.as_object() {
if let Some(object) = object.as_object() {
let key = args
.get(1)
.unwrap_or(&Value::undefined())
Expand Down
9 changes: 0 additions & 9 deletions boa/src/builtins/regexp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,50 +78,41 @@ impl BuiltIn for RegExp {
let get_species = FunctionBuilder::new(context, Self::get_species)
.name("get [Symbol.species]")
.constructable(false)
.callable(true)
.build();

let flag_attributes = Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE;

let get_global = FunctionBuilder::new(context, Self::get_global)
.name("get global")
.constructable(false)
.callable(true)
.build();
let get_ignore_case = FunctionBuilder::new(context, Self::get_ignore_case)
.name("get ignoreCase")
.constructable(false)
.callable(true)
.build();
let get_multiline = FunctionBuilder::new(context, Self::get_multiline)
.name("get multiline")
.constructable(false)
.callable(true)
.build();
let get_dot_all = FunctionBuilder::new(context, Self::get_dot_all)
.name("get dotAll")
.constructable(false)
.callable(true)
.build();
let get_unicode = FunctionBuilder::new(context, Self::get_unicode)
.name("get unicode")
.constructable(false)
.callable(true)
.build();
let get_sticky = FunctionBuilder::new(context, Self::get_sticky)
.name("get sticky")
.constructable(false)
.callable(true)
.build();
let get_flags = FunctionBuilder::new(context, Self::get_flags)
.name("get flags")
.constructable(false)
.callable(true)
.build();
let get_source = FunctionBuilder::new(context, Self::get_source)
.name("get source")
.constructable(false)
.callable(true)
.build();
let regexp_object = ConstructorBuilder::with_standard_object(
context,
Expand Down
3 changes: 0 additions & 3 deletions boa/src/builtins/set/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,9 @@ impl BuiltIn for Set {
let get_species = FunctionBuilder::new(context, Self::get_species)
.name("get [Symbol.species]")
.constructable(false)
.callable(true)
.build();

let size_getter = FunctionBuilder::new(context, Self::size_getter)
.callable(true)
.constructable(false)
.name("get size")
.build();
Expand All @@ -58,7 +56,6 @@ impl BuiltIn for Set {
let values_function = FunctionBuilder::new(context, Self::values)
.name("values")
.length(0)
.callable(true)
.constructable(false)
.build();

Expand Down
1 change: 0 additions & 1 deletion boa/src/builtins/symbol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ impl BuiltIn for Symbol {
let get_description = FunctionBuilder::new(context, Self::get_description)
.name("get description")
.constructable(false)
.callable(true)
.build();

let symbol_object = ConstructorBuilder::with_standard_object(
Expand Down

0 comments on commit b1f2b95

Please sign in to comment.