Skip to content

Commit

Permalink
Merge 16ce549 into d837e04
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat authored May 27, 2020
2 parents d837e04 + 16ce549 commit b1ff14c
Show file tree
Hide file tree
Showing 14 changed files with 194 additions and 267 deletions.
8 changes: 4 additions & 4 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use super::function::{make_builtin_fn, make_constructor_fn};
use crate::{
builtins::{
error::RangeError,
object::{ObjectKind, INSTANCE_PROTOTYPE, PROTOTYPE},
object::{ObjectData, INSTANCE_PROTOTYPE, PROTOTYPE},
property::Property,
value::{same_value_zero, ResultValue, Value, ValueData},
},
Expand All @@ -42,7 +42,7 @@ impl Array {
.get_global_object()
.expect("Could not get global object"),
));
array.set_kind(ObjectKind::Array);
array.set_data(ObjectData::Array);
array.borrow().set_internal_slot(
INSTANCE_PROTOTYPE,
interpreter
Expand Down Expand Up @@ -117,7 +117,7 @@ impl Array {
this.set_internal_slot(INSTANCE_PROTOTYPE, prototype);
// This value is used by console.log and other routines to match Object type
// to its Javascript Identifier (global constructor method name)
this.set_kind(ObjectKind::Array);
this.set_data(ObjectData::Array);

// add our arguments in
let mut length = args.len() as i32;
Expand Down Expand Up @@ -176,7 +176,7 @@ impl Array {
// 1.
ValueData::Object(ref obj) => {
// 2.
if (*obj).deref().borrow().kind == ObjectKind::Array {
if let ObjectData::Array = (*obj).deref().borrow().data {
return Ok(value_true);
}
Ok(value_false)
Expand Down
13 changes: 4 additions & 9 deletions boa/src/builtins/bigint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,11 @@ impl BigInt {
///
/// [spec]: https://tc39.es/ecma262/#sec-bigint-objects
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/BigInt
pub(crate) fn make_bigint(
_this: &mut Value,
args: &[Value],
ctx: &mut Interpreter,
) -> ResultValue {
pub(crate) fn make_bigint(_: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let data = match args.get(0) {
Some(ref value) => {
if let Some(bigint) = value.to_bigint() {
Value::from(bigint)
bigint
} else {
return Err(RangeError::run_new(
format!(
Expand All @@ -59,9 +55,9 @@ impl BigInt {
)?);
}
}
None => Value::from(AstBigInt::from(0)),
None => AstBigInt::from(0),
};
Ok(data)
Ok(Value::from(data))
}

/// `BigInt.prototype.toString( [radix] )`
Expand Down Expand Up @@ -119,7 +115,6 @@ impl BigInt {
/// Create a new `Number` object
pub(crate) fn create(global: &Value) -> Value {
let prototype = Value::new_object(Some(global));
prototype.set_internal_slot("BigIntData", Value::from(AstBigInt::from(0)));

make_builtin_fn(Self::to_string, "toString", &prototype, 1);
make_builtin_fn(Self::value_of, "valueOf", &prototype, 0);
Expand Down
45 changes: 12 additions & 33 deletions boa/src/builtins/boolean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod tests;
use super::function::{make_builtin_fn, make_constructor_fn};
use crate::{
builtins::{
object::{internal_methods_trait::ObjectInternalMethods, ObjectKind},
object::ObjectData,
value::{ResultValue, Value, ValueData},
},
exec::Interpreter,
Expand All @@ -35,19 +35,11 @@ impl Boolean {
args: &[Value],
_: &mut Interpreter,
) -> ResultValue {
this.set_kind(ObjectKind::Boolean);

// Get the argument, if any
if let Some(ref value) = args.get(0) {
this.set_internal_slot("BooleanData", Self::to_boolean(value));
} else {
this.set_internal_slot("BooleanData", Self::to_boolean(&Value::from(false)));
}
let data = args.get(0).map(|x| x.to_boolean()).unwrap_or(false);
this.set_data(ObjectData::Boolean(data));

match args.get(0) {
Some(ref value) => Ok(Self::to_boolean(value)),
None => Ok(Self::to_boolean(&Value::from(false))),
}
Ok(Value::from(data))
}

/// The `toString()` method returns a string representing the specified `Boolean` object.
Expand All @@ -73,22 +65,7 @@ impl Boolean {
/// [spec]: https://tc39.es/ecma262/#sec-boolean.prototype.valueof
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean/valueOf
pub(crate) fn value_of(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
Ok(Self::this_boolean_value(this))
}

// === Utility Functions ===
/// [toBoolean](https://tc39.es/ecma262/#sec-toboolean)
/// Creates a new boolean value from the input
#[allow(clippy::wrong_self_convention)]
pub(crate) fn to_boolean(value: &Value) -> Value {
match *value.deref().borrow() {
ValueData::Object(_) => Value::from(true),
ValueData::String(ref s) if !s.is_empty() => Value::from(true),
ValueData::Rational(n) if n != 0.0 && !n.is_nan() => Value::from(true),
ValueData::Integer(n) if n != 0 => Value::from(true),
ValueData::Boolean(v) => Value::from(v),
_ => Value::from(false),
}
Ok(Value::from(Self::this_boolean_value(this)))
}

/// An Utility function used to get the internal BooleanData.
Expand All @@ -97,11 +74,14 @@ impl Boolean {
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-thisbooleanvalue
pub(crate) fn this_boolean_value(value: &Value) -> Value {
pub(crate) fn this_boolean_value(value: &Value) -> bool {
match *value.deref().borrow() {
ValueData::Boolean(v) => Value::from(v),
ValueData::Object(ref v) => (v).deref().borrow().get_internal_slot("BooleanData"),
_ => Value::from(false),
ValueData::Boolean(v) => v,
ValueData::Object(ref v) => match v.deref().borrow().data {
ObjectData::Boolean(boolean) => boolean,
_ => unreachable!(),
},
_ => false,
}
}

Expand All @@ -110,7 +90,6 @@ impl Boolean {
// Create Prototype
// https://tc39.es/ecma262/#sec-properties-of-the-boolean-prototype-object
let prototype = Value::new_object(Some(global));
prototype.set_internal_slot("BooleanData", Self::to_boolean(&Value::from(false)));

make_builtin_fn(Self::to_string, "toString", &prototype, 0);
make_builtin_fn(Self::value_of, "valueOf", &prototype, 0);
Expand Down
4 changes: 2 additions & 2 deletions boa/src/builtins/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use crate::{
builtins::{
function::{make_builtin_fn, make_constructor_fn},
object::ObjectKind,
object::ObjectData,
value::{ResultValue, Value},
},
exec::Interpreter,
Expand Down Expand Up @@ -47,7 +47,7 @@ impl Error {
}
// This value is used by console.log and other routines to match Object type
// to its Javascript Identifier (global constructor method name)
this.set_kind(ObjectKind::Error);
this.set_data(ObjectData::Error);
Ok(Value::undefined())
}

Expand Down
4 changes: 2 additions & 2 deletions boa/src/builtins/error/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
builtins::{
function::make_builtin_fn,
function::make_constructor_fn,
object::ObjectKind,
object::ObjectData,
value::{ResultValue, Value},
},
exec::Interpreter,
Expand All @@ -38,7 +38,7 @@ impl RangeError {
}
// This value is used by console.log and other routines to match Object type
// to its Javascript Identifier (global constructor method name)
this.set_kind(ObjectKind::Error);
this.set_data(ObjectData::Error);
Ok(Value::undefined())
}

Expand Down
39 changes: 19 additions & 20 deletions boa/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use crate::{
builtins::{
array::Array,
object::{Object, ObjectInternalMethods, ObjectKind, INSTANCE_PROTOTYPE, PROTOTYPE},
object::{Object, ObjectData, ObjectInternalMethods, INSTANCE_PROTOTYPE, PROTOTYPE},
property::Property,
value::{ResultValue, Value},
},
Expand Down Expand Up @@ -55,7 +55,7 @@ pub enum FunctionBody {
impl Debug for FunctionBody {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::BuiltIn(_) => write!(f, "native code"),
Self::BuiltIn(_) => write!(f, "[native]"),
Self::Ordinary(statements) => write!(f, "{:?}", statements),
}
}
Expand Down Expand Up @@ -158,19 +158,19 @@ impl Function {
/// <https://tc39.es/ecma262/#sec-ecmascript-function-objects-call-thisargument-argumentslist>
pub fn call(
&self,
this: &mut Value, // represents a pointer to this function object wrapped in a GC (not a `this` JS object)
function: Value, // represents a pointer to this function object wrapped in a GC (not a `this` JS object)
this: &mut Value,
args_list: &[Value],
interpreter: &mut Interpreter,
this_obj: &mut Value,
) -> ResultValue {
if self.callable {
match self.body {
FunctionBody::BuiltIn(func) => func(this_obj, args_list, interpreter),
FunctionBody::BuiltIn(func) => func(this, args_list, interpreter),
FunctionBody::Ordinary(ref body) => {
// Create a new Function environment who's parent is set to the scope of the function declaration (self.environment)
// <https://tc39.es/ecma262/#sec-prepareforordinarycall>
let local_env = new_function_environment(
this.clone(),
function,
None,
Some(self.environment.as_ref().unwrap().clone()),
BindingStatus::Uninitialized,
Expand Down Expand Up @@ -216,23 +216,23 @@ impl Function {
/// <https://tc39.es/ecma262/#sec-ecmascript-function-objects-construct-argumentslist-newtarget>
pub fn construct(
&self,
this: &mut Value, // represents a pointer to this function object wrapped in a GC (not a `this` JS object)
function: Value, // represents a pointer to this function object wrapped in a GC (not a `this` JS object)
this: &mut Value,
args_list: &[Value],
interpreter: &mut Interpreter,
this_obj: &mut Value,
) -> ResultValue {
if self.constructable {
match self.body {
FunctionBody::BuiltIn(func) => {
func(this_obj, args_list, interpreter).unwrap();
Ok(this_obj.clone())
func(this, args_list, interpreter)?;
Ok(this.clone())
}
FunctionBody::Ordinary(ref body) => {
// Create a new Function environment who's parent is set to the scope of the function declaration (self.environment)
// <https://tc39.es/ecma262/#sec-prepareforordinarycall>
let local_env = new_function_environment(
this.clone(),
Some(this_obj.clone()),
function,
Some(this.clone()),
Some(self.environment.as_ref().unwrap().clone()),
BindingStatus::Initialized,
);
Expand Down Expand Up @@ -368,7 +368,10 @@ pub fn create_unmapped_arguments_object(arguments_list: &[Value]) -> Value {
///
// This gets called when a new Function() is created.
pub fn make_function(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
this.set_kind(ObjectKind::Function);
this.set_data(ObjectData::Function(Function::builtin(
Vec::new(),
|_, _, _| Ok(Value::undefined()),
)));
Ok(this.clone())
}

Expand Down Expand Up @@ -399,8 +402,7 @@ pub fn make_constructor_fn(
let func_prototype = global.get_field("Function").get_field(PROTOTYPE);

// Create the function object and point its instance prototype to Function.prototype
let mut constructor_obj = Object::function();
constructor_obj.set_func(constructor_fn);
let mut constructor_obj = Object::function(constructor_fn);

constructor_obj.set_internal_slot(INSTANCE_PROTOTYPE, func_prototype);
let constructor_val = Value::from(constructor_obj);
Expand Down Expand Up @@ -433,12 +435,9 @@ pub fn make_builtin_fn<N>(function: NativeFunctionData, name: N, parent: &Value,
where
N: Into<String>,
{
let func = Function::builtin(Vec::new(), function);
let func = Object::function(Function::builtin(Vec::new(), function));

let mut new_func = Object::function();
new_func.set_func(func);

let new_func_obj = Value::from(new_func);
let new_func_obj = Value::from(func);
new_func_obj.set_field("length", length);

parent.set_field(name.into(), new_func_obj);
Expand Down
28 changes: 14 additions & 14 deletions boa/src/builtins/number/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,17 @@ mod tests;

use super::{
function::{make_builtin_fn, make_constructor_fn},
object::ObjectKind,
object::ObjectData,
};
use crate::{
builtins::{
object::internal_methods_trait::ObjectInternalMethods,
value::{ResultValue, Value, ValueData},
RangeError,
},
exec::Interpreter,
};
use num_traits::float::FloatCore;
use std::{borrow::Borrow, f64, ops::Deref};
use std::{f64, ops::Deref};

const BUF_SIZE: usize = 2200;

Expand All @@ -41,19 +40,22 @@ impl Number {
/// Helper function that converts a Value to a Number.
#[allow(clippy::wrong_self_convention)]
fn to_number(value: &Value) -> Value {
match *value.deref().borrow() {
match value.data() {
ValueData::Boolean(b) => {
if b {
if *b {
Value::from(1)
} else {
Value::from(0)
}
}
ValueData::Symbol(_) | ValueData::Undefined => Value::from(f64::NAN),
ValueData::Integer(i) => Value::from(f64::from(i)),
ValueData::Object(ref o) => (o).deref().borrow().get_internal_slot("NumberData"),
ValueData::Integer(i) => Value::from(f64::from(*i)),
ValueData::Object(ref o) => match (o).deref().borrow().data {
ObjectData::Number(num) => Value::from(num),
_ => unreachable!(),
},
ValueData::Null => Value::from(0),
ValueData::Rational(n) => Value::from(n),
ValueData::Rational(n) => Value::from(*n),
ValueData::BigInt(ref bigint) => Value::from(bigint.to_f64()),
ValueData::String(ref s) => match s.parse::<f64>() {
Ok(n) => Value::from(n),
Expand All @@ -80,13 +82,12 @@ impl Number {
_ctx: &mut Interpreter,
) -> ResultValue {
let data = match args.get(0) {
Some(ref value) => Self::to_number(value),
None => Self::to_number(&Value::from(0)),
Some(ref value) => Self::to_number(value).to_number(),
None => 0.0,
};
this.set_kind(ObjectKind::Number);
this.set_internal_slot("NumberData", data.clone());
this.set_data(ObjectData::Number(data));

Ok(data)
Ok(Value::from(data))
}

/// `Number.prototype.toExponential( [fractionDigits] )`
Expand Down Expand Up @@ -393,7 +394,6 @@ impl Number {
/// Create a new `Number` object
pub(crate) fn create(global: &Value) -> Value {
let prototype = Value::new_object(Some(global));
prototype.set_internal_slot("NumberData", Value::from(0));

make_builtin_fn(Self::to_exponential, "toExponential", &prototype, 1);
make_builtin_fn(Self::to_fixed, "toFixed", &prototype, 1);
Expand Down
Loading

0 comments on commit b1ff14c

Please sign in to comment.