Skip to content

Commit 62bdd68

Browse files
committed
Specialized Number, String and Boolean objects
1 parent d42e413 commit 62bdd68

12 files changed

Lines changed: 127 additions & 189 deletions

File tree

boa/src/builtins/array/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use super::function::{make_builtin_fn, make_constructor_fn};
1616
use crate::{
1717
builtins::{
1818
error::RangeError,
19-
object::{ObjectKind, INSTANCE_PROTOTYPE, PROTOTYPE},
19+
object::{ObjectData, INSTANCE_PROTOTYPE, PROTOTYPE},
2020
property::Property,
2121
value::{same_value_zero, ResultValue, Value, ValueData},
2222
},
@@ -42,7 +42,7 @@ impl Array {
4242
.get_global_object()
4343
.expect("Could not get global object"),
4444
));
45-
array.set_kind(ObjectKind::Array);
45+
array.set_data(ObjectData::Array);
4646
array.borrow().set_internal_slot(
4747
INSTANCE_PROTOTYPE,
4848
interpreter
@@ -117,7 +117,7 @@ impl Array {
117117
this.set_internal_slot(INSTANCE_PROTOTYPE, prototype);
118118
// This value is used by console.log and other routines to match Object type
119119
// to its Javascript Identifier (global constructor method name)
120-
this.set_kind(ObjectKind::Array);
120+
this.set_data(ObjectData::Array);
121121

122122
// add our arguments in
123123
let mut length = args.len() as i32;
@@ -176,7 +176,7 @@ impl Array {
176176
// 1.
177177
ValueData::Object(ref obj) => {
178178
// 2.
179-
if (*obj).deref().borrow().kind == ObjectKind::Array {
179+
if (*obj).deref().borrow().data == ObjectData::Array {
180180
return Ok(value_true);
181181
}
182182
Ok(value_false)

boa/src/builtins/boolean/mod.rs

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ mod tests;
1515
use super::function::{make_builtin_fn, make_constructor_fn};
1616
use crate::{
1717
builtins::{
18-
object::{internal_methods_trait::ObjectInternalMethods, ObjectKind},
18+
object::ObjectData,
1919
value::{ResultValue, Value, ValueData},
2020
},
2121
exec::Interpreter,
@@ -35,19 +35,11 @@ impl Boolean {
3535
args: &[Value],
3636
_: &mut Interpreter,
3737
) -> ResultValue {
38-
this.set_kind(ObjectKind::Boolean);
39-
4038
// Get the argument, if any
41-
if let Some(ref value) = args.get(0) {
42-
this.set_internal_slot("BooleanData", Self::to_boolean(value));
43-
} else {
44-
this.set_internal_slot("BooleanData", Self::to_boolean(&Value::from(false)));
45-
}
39+
let data = args.get(0).map(|x| x.to_boolean()).unwrap_or(false);
40+
this.set_data(ObjectData::Boolean(data));
4641

47-
match args.get(0) {
48-
Some(ref value) => Ok(Self::to_boolean(value)),
49-
None => Ok(Self::to_boolean(&Value::from(false))),
50-
}
42+
Ok(Value::from(data))
5143
}
5244

5345
/// The `toString()` method returns a string representing the specified `Boolean` object.
@@ -73,22 +65,7 @@ impl Boolean {
7365
/// [spec]: https://tc39.es/ecma262/#sec-boolean.prototype.valueof
7466
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean/valueOf
7567
pub(crate) fn value_of(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
76-
Ok(Self::this_boolean_value(this))
77-
}
78-
79-
// === Utility Functions ===
80-
/// [toBoolean](https://tc39.es/ecma262/#sec-toboolean)
81-
/// Creates a new boolean value from the input
82-
#[allow(clippy::wrong_self_convention)]
83-
pub(crate) fn to_boolean(value: &Value) -> Value {
84-
match *value.deref().borrow() {
85-
ValueData::Object(_) => Value::from(true),
86-
ValueData::String(ref s) if !s.is_empty() => Value::from(true),
87-
ValueData::Rational(n) if n != 0.0 && !n.is_nan() => Value::from(true),
88-
ValueData::Integer(n) if n != 0 => Value::from(true),
89-
ValueData::Boolean(v) => Value::from(v),
90-
_ => Value::from(false),
91-
}
68+
Ok(Value::from(Self::this_boolean_value(this)))
9269
}
9370

9471
/// An Utility function used to get the internal BooleanData.
@@ -97,11 +74,14 @@ impl Boolean {
9774
/// - [ECMAScript reference][spec]
9875
///
9976
/// [spec]: https://tc39.es/ecma262/#sec-thisbooleanvalue
100-
pub(crate) fn this_boolean_value(value: &Value) -> Value {
77+
pub(crate) fn this_boolean_value(value: &Value) -> bool {
10178
match *value.deref().borrow() {
102-
ValueData::Boolean(v) => Value::from(v),
103-
ValueData::Object(ref v) => (v).deref().borrow().get_internal_slot("BooleanData"),
104-
_ => Value::from(false),
79+
ValueData::Boolean(v) => v,
80+
ValueData::Object(ref v) => match v.deref().borrow().data {
81+
ObjectData::Boolean(boolean) => boolean,
82+
_ => unreachable!(),
83+
},
84+
_ => false,
10585
}
10686
}
10787

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

11594
make_builtin_fn(Self::to_string, "toString", &prototype, 0);
11695
make_builtin_fn(Self::value_of, "valueOf", &prototype, 0);

boa/src/builtins/error/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use crate::{
1414
builtins::{
1515
function::{make_builtin_fn, make_constructor_fn},
16-
object::ObjectKind,
16+
object::ObjectData,
1717
value::{ResultValue, Value},
1818
},
1919
exec::Interpreter,
@@ -47,7 +47,7 @@ impl Error {
4747
}
4848
// This value is used by console.log and other routines to match Object type
4949
// to its Javascript Identifier (global constructor method name)
50-
this.set_kind(ObjectKind::Error);
50+
this.set_data(ObjectData::Error);
5151
Ok(Value::undefined())
5252
}
5353

boa/src/builtins/error/range.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
builtins::{
1414
function::make_builtin_fn,
1515
function::make_constructor_fn,
16-
object::ObjectKind,
16+
object::ObjectData,
1717
value::{ResultValue, Value},
1818
},
1919
exec::Interpreter,
@@ -38,7 +38,7 @@ impl RangeError {
3838
}
3939
// This value is used by console.log and other routines to match Object type
4040
// to its Javascript Identifier (global constructor method name)
41-
this.set_kind(ObjectKind::Error);
41+
this.set_data(ObjectData::Error);
4242
Ok(Value::undefined())
4343
}
4444

boa/src/builtins/function/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use crate::{
1515
builtins::{
1616
array::Array,
17-
object::{Object, ObjectInternalMethods, ObjectKind, INSTANCE_PROTOTYPE, PROTOTYPE},
17+
object::{Object, ObjectData, ObjectInternalMethods, INSTANCE_PROTOTYPE, PROTOTYPE},
1818
property::Property,
1919
value::{ResultValue, Value},
2020
},
@@ -368,7 +368,7 @@ pub fn create_unmapped_arguments_object(arguments_list: &[Value]) -> Value {
368368
///
369369
// This gets called when a new Function() is created.
370370
pub fn make_function(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
371-
this.set_kind(ObjectKind::Function);
371+
this.set_data(ObjectData::Function);
372372
Ok(this.clone())
373373
}
374374

boa/src/builtins/number/mod.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,17 @@ mod tests;
1818

1919
use super::{
2020
function::{make_builtin_fn, make_constructor_fn},
21-
object::ObjectKind,
21+
object::ObjectData,
2222
};
2323
use crate::{
2424
builtins::{
25-
object::internal_methods_trait::ObjectInternalMethods,
2625
value::{ResultValue, Value, ValueData},
2726
RangeError,
2827
},
2928
exec::Interpreter,
3029
};
3130
use num_traits::float::FloatCore;
32-
use std::{borrow::Borrow, f64, ops::Deref};
31+
use std::{f64, ops::Deref};
3332

3433
const BUF_SIZE: usize = 2200;
3534

@@ -41,19 +40,22 @@ impl Number {
4140
/// Helper function that converts a Value to a Number.
4241
#[allow(clippy::wrong_self_convention)]
4342
fn to_number(value: &Value) -> Value {
44-
match *value.deref().borrow() {
43+
match value.data() {
4544
ValueData::Boolean(b) => {
46-
if b {
45+
if *b {
4746
Value::from(1)
4847
} else {
4948
Value::from(0)
5049
}
5150
}
5251
ValueData::Symbol(_) | ValueData::Undefined => Value::from(f64::NAN),
53-
ValueData::Integer(i) => Value::from(f64::from(i)),
54-
ValueData::Object(ref o) => (o).deref().borrow().get_internal_slot("NumberData"),
52+
ValueData::Integer(i) => Value::from(f64::from(*i)),
53+
ValueData::Object(ref o) => match (o).deref().borrow().data {
54+
ObjectData::Number(num) => Value::from(num),
55+
_ => unreachable!(),
56+
},
5557
ValueData::Null => Value::from(0),
56-
ValueData::Rational(n) => Value::from(n),
58+
ValueData::Rational(n) => Value::from(*n),
5759
ValueData::BigInt(ref bigint) => Value::from(bigint.to_f64()),
5860
ValueData::String(ref s) => match s.parse::<f64>() {
5961
Ok(n) => Value::from(n),
@@ -80,13 +82,12 @@ impl Number {
8082
_ctx: &mut Interpreter,
8183
) -> ResultValue {
8284
let data = match args.get(0) {
83-
Some(ref value) => Self::to_number(value),
84-
None => Self::to_number(&Value::from(0)),
85+
Some(ref value) => Self::to_number(value).to_number(),
86+
None => 0.0,
8587
};
86-
this.set_kind(ObjectKind::Number);
87-
this.set_internal_slot("NumberData", data.clone());
88+
this.set_data(ObjectData::Number(data));
8889

89-
Ok(data)
90+
Ok(Value::from(data))
9091
}
9192

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

398398
make_builtin_fn(Self::to_exponential, "toExponential", &prototype, 1);
399399
make_builtin_fn(Self::to_fixed, "toFixed", &prototype, 1);

0 commit comments

Comments
 (0)