Skip to content

Commit b52be12

Browse files
authored
Merge 1b76706 into d837e04
2 parents d837e04 + 1b76706 commit b52be12

File tree

14 files changed

+184
-267
lines changed

14 files changed

+184
-267
lines changed

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 let ObjectData::Array = (*obj).deref().borrow().data {
180180
return Ok(value_true);
181181
}
182182
Ok(value_false)

boa/src/builtins/bigint/mod.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,11 @@ impl BigInt {
4040
///
4141
/// [spec]: https://tc39.es/ecma262/#sec-bigint-objects
4242
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/BigInt
43-
pub(crate) fn make_bigint(
44-
_this: &mut Value,
45-
args: &[Value],
46-
ctx: &mut Interpreter,
47-
) -> ResultValue {
43+
pub(crate) fn make_bigint(_: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
4844
let data = match args.get(0) {
4945
Some(ref value) => {
5046
if let Some(bigint) = value.to_bigint() {
51-
Value::from(bigint)
47+
bigint
5248
} else {
5349
return Err(RangeError::run_new(
5450
format!(
@@ -59,9 +55,9 @@ impl BigInt {
5955
)?);
6056
}
6157
}
62-
None => Value::from(AstBigInt::from(0)),
58+
None => AstBigInt::from(0),
6359
};
64-
Ok(data)
60+
Ok(Value::from(data))
6561
}
6662

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

124119
make_builtin_fn(Self::to_string, "toString", &prototype, 1);
125120
make_builtin_fn(Self::value_of, "valueOf", &prototype, 0);

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: 19 additions & 20 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
},
@@ -55,7 +55,7 @@ pub enum FunctionBody {
5555
impl Debug for FunctionBody {
5656
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5757
match self {
58-
Self::BuiltIn(_) => write!(f, "native code"),
58+
Self::BuiltIn(_) => write!(f, "[native]"),
5959
Self::Ordinary(statements) => write!(f, "{:?}", statements),
6060
}
6161
}
@@ -158,19 +158,19 @@ impl Function {
158158
/// <https://tc39.es/ecma262/#sec-ecmascript-function-objects-call-thisargument-argumentslist>
159159
pub fn call(
160160
&self,
161-
this: &mut Value, // represents a pointer to this function object wrapped in a GC (not a `this` JS object)
161+
function: Value, // represents a pointer to this function object wrapped in a GC (not a `this` JS object)
162+
this: &mut Value,
162163
args_list: &[Value],
163164
interpreter: &mut Interpreter,
164-
this_obj: &mut Value,
165165
) -> ResultValue {
166166
if self.callable {
167167
match self.body {
168-
FunctionBody::BuiltIn(func) => func(this_obj, args_list, interpreter),
168+
FunctionBody::BuiltIn(func) => func(this, args_list, interpreter),
169169
FunctionBody::Ordinary(ref body) => {
170170
// Create a new Function environment who's parent is set to the scope of the function declaration (self.environment)
171171
// <https://tc39.es/ecma262/#sec-prepareforordinarycall>
172172
let local_env = new_function_environment(
173-
this.clone(),
173+
function,
174174
None,
175175
Some(self.environment.as_ref().unwrap().clone()),
176176
BindingStatus::Uninitialized,
@@ -216,23 +216,23 @@ impl Function {
216216
/// <https://tc39.es/ecma262/#sec-ecmascript-function-objects-construct-argumentslist-newtarget>
217217
pub fn construct(
218218
&self,
219-
this: &mut Value, // represents a pointer to this function object wrapped in a GC (not a `this` JS object)
219+
function: Value, // represents a pointer to this function object wrapped in a GC (not a `this` JS object)
220+
this: &mut Value,
220221
args_list: &[Value],
221222
interpreter: &mut Interpreter,
222-
this_obj: &mut Value,
223223
) -> ResultValue {
224224
if self.constructable {
225225
match self.body {
226226
FunctionBody::BuiltIn(func) => {
227-
func(this_obj, args_list, interpreter).unwrap();
228-
Ok(this_obj.clone())
227+
func(this, args_list, interpreter)?;
228+
Ok(this.clone())
229229
}
230230
FunctionBody::Ordinary(ref body) => {
231231
// Create a new Function environment who's parent is set to the scope of the function declaration (self.environment)
232232
// <https://tc39.es/ecma262/#sec-prepareforordinarycall>
233233
let local_env = new_function_environment(
234-
this.clone(),
235-
Some(this_obj.clone()),
234+
function,
235+
Some(this.clone()),
236236
Some(self.environment.as_ref().unwrap().clone()),
237237
BindingStatus::Initialized,
238238
);
@@ -368,7 +368,10 @@ 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(Function::builtin(
372+
Vec::new(),
373+
|_, _, _| Ok(Value::undefined()),
374+
)));
372375
Ok(this.clone())
373376
}
374377

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

401404
// Create the function object and point its instance prototype to Function.prototype
402-
let mut constructor_obj = Object::function();
403-
constructor_obj.set_func(constructor_fn);
405+
let mut constructor_obj = Object::function(constructor_fn);
404406

405407
constructor_obj.set_internal_slot(INSTANCE_PROTOTYPE, func_prototype);
406408
let constructor_val = Value::from(constructor_obj);
@@ -433,12 +435,9 @@ pub fn make_builtin_fn<N>(function: NativeFunctionData, name: N, parent: &Value,
433435
where
434436
N: Into<String>,
435437
{
436-
let func = Function::builtin(Vec::new(), function);
438+
let func = Object::function(Function::builtin(Vec::new(), function));
437439

438-
let mut new_func = Object::function();
439-
new_func.set_func(func);
440-
441-
let new_func_obj = Value::from(new_func);
440+
let new_func_obj = Value::from(func);
442441
new_func_obj.set_field("length", length);
443442

444443
parent.set_field(name.into(), new_func_obj);

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)