Skip to content

Commit

Permalink
Merge eaf586d into 08a608a
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat authored Jul 20, 2020
2 parents 08a608a + eaf586d commit ba450bc
Show file tree
Hide file tree
Showing 15 changed files with 99 additions and 79 deletions.
25 changes: 12 additions & 13 deletions boa/src/builtins/array/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::{ObjectData, INSTANCE_PROTOTYPE, PROTOTYPE},
object::{ObjectData, PROTOTYPE},
property::Property,
value::{same_value_zero, ResultValue, Value},
},
Expand Down Expand Up @@ -48,16 +48,13 @@ impl Array {
.expect("Could not get global object"),
));
array.set_data(ObjectData::Array);
array.borrow().set_internal_slot(
INSTANCE_PROTOTYPE,
interpreter
.realm()
.environment
.get_binding_value("Array")
.expect("Array was not initialized")
.borrow()
.get_field(PROTOTYPE),
);
array.as_object_mut().unwrap().prototype = interpreter
.realm()
.environment
.get_binding_value("Array")
.expect("Array was not initialized")
.borrow()
.get_field(PROTOTYPE);
array.borrow().set_field("length", Value::from(0));
Ok(array)
}
Expand Down Expand Up @@ -116,7 +113,9 @@ impl Array {
// Set Prototype
let prototype = ctx.realm.global_obj.get_field("Array").get_field(PROTOTYPE);

this.set_internal_slot(INSTANCE_PROTOTYPE, prototype);
this.as_object_mut()
.expect("this should be an array object")
.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_data(ObjectData::Array);
Expand Down Expand Up @@ -961,7 +960,7 @@ impl Array {
///
/// The reduce method traverses left to right starting from the first defined value in the array,
/// accumulating a value using a given callback function. It returns the accumulated value.
///
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
Expand Down
4 changes: 2 additions & 2 deletions boa/src/builtins/boolean/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{builtins::value::same_value, exec::Interpreter, forward, forward_val, realm::Realm};

/// Test the correct type is returned from call and construct
#[allow(clippy::result_unwrap_used)]
#[allow(clippy::unwrap_used)]
#[test]
fn construct_and_call() {
let realm = Realm::create();
Expand Down Expand Up @@ -62,7 +62,7 @@ fn instances_have_correct_proto_set() {
let bool_prototype = forward_val(&mut engine, "boolProto").expect("value expected");

assert!(same_value(
&bool_instance.get_internal_slot("__proto__"),
&bool_instance.as_object().unwrap().prototype().clone(),
&bool_prototype
));
}
7 changes: 2 additions & 5 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, ObjectData, INSTANCE_PROTOTYPE, PROTOTYPE},
object::{Object, ObjectData, PROTOTYPE},
property::Property,
value::{RcString, ResultValue, Value},
},
Expand Down Expand Up @@ -468,10 +468,7 @@ pub fn make_constructor_fn(

// Get reference to Function.prototype
// Create the function object and point its instance prototype to Function.prototype
constructor.set_internal_slot(
INSTANCE_PROTOTYPE,
global.get_field("Function").get_field(PROTOTYPE),
);
constructor.prototype = global.get_field("Function").get_field(PROTOTYPE);

let length = Property::new()
.value(Value::from(length))
Expand Down
15 changes: 9 additions & 6 deletions boa/src/builtins/json/tests.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use crate::{
builtins::{
object::{INSTANCE_PROTOTYPE, PROTOTYPE},
value::same_value,
},
builtins::{object::PROTOTYPE, value::same_value},
exec::Interpreter,
forward, forward_val,
realm::Realm,
Expand Down Expand Up @@ -284,10 +281,16 @@ fn json_parse_sets_prototypes() {
eprintln!("{}", forward(&mut engine, init));
let object_prototype = forward_val(&mut engine, r#"jsonObj.ob"#)
.unwrap()
.get_internal_slot(INSTANCE_PROTOTYPE);
.as_object()
.unwrap()
.prototype()
.clone();
let array_prototype = forward_val(&mut engine, r#"jsonObj.arr"#)
.unwrap()
.get_internal_slot(INSTANCE_PROTOTYPE);
.as_object()
.unwrap()
.prototype()
.clone();
let global_object_prototype = engine
.realm
.global_obj
Expand Down
6 changes: 4 additions & 2 deletions boa/src/builtins/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use super::function::{make_builtin_fn, make_constructor_fn};
use crate::{
builtins::{
object::{ObjectData, INSTANCE_PROTOTYPE, PROTOTYPE},
object::{ObjectData, PROTOTYPE},
property::Property,
value::{ResultValue, Value},
},
Expand Down Expand Up @@ -235,7 +235,9 @@ impl Map {
// Set Prototype
let prototype = ctx.realm.global_obj.get_field("Map").get_field(PROTOTYPE);

this.set_internal_slot(INSTANCE_PROTOTYPE, prototype);
this.as_object_mut()
.expect("this is array object")
.prototype = prototype;
// This value is used by console.log and other routines to match Object type
// to its Javascript Identifier (global constructor method name)

Expand Down
4 changes: 2 additions & 2 deletions boa/src/builtins/object/internal_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//! [spec]: https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots
use crate::builtins::{
object::{Object, INSTANCE_PROTOTYPE, PROTOTYPE},
object::{Object, PROTOTYPE},
property::Property,
value::{same_value, RcString, Value},
};
Expand Down Expand Up @@ -363,7 +363,7 @@ impl Object {
/// [spec]: https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-getprototypeof
#[inline]
pub fn get_prototype_of(&self) -> Value {
self.get_internal_slot(INSTANCE_PROTOTYPE)
self.prototype.clone()
}

/// Helper function to get an immutable internal slot or `Null`.
Expand Down
25 changes: 19 additions & 6 deletions boa/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ mod tests;
/// Static `prototype`, usually set on constructors as a key to point to their respective prototype object.
pub static PROTOTYPE: &str = "prototype";

/// Static `__proto__`, usually set on Object instances as a key to point to their respective prototype object.
pub static INSTANCE_PROTOTYPE: &str = "__proto__";
// /// Static `__proto__`, usually set on Object instances as a key to point to their respective prototype object.
// pub static INSTANCE_PROTOTYPE: &str = "__proto__";

/// The internal representation of an JavaScript object.
#[derive(Debug, Trace, Finalize, Clone)]
Expand All @@ -58,6 +58,8 @@ pub struct Object {
properties: FxHashMap<RcString, Property>,
/// Symbol Properties
symbol_properties: FxHashMap<u32, Property>,
/// Instance prototype `__proto__`.
pub(crate) prototype: Value,
/// Some rust object that stores internal state
state: Option<InternalStateCell>,
/// Whether it can have new properties added to it.
Expand Down Expand Up @@ -109,6 +111,7 @@ impl Default for Object {
internal_slots: FxHashMap::default(),
properties: FxHashMap::default(),
symbol_properties: FxHashMap::default(),
prototype: Value::null(),
state: None,
extensible: true,
}
Expand All @@ -130,6 +133,7 @@ impl Object {
internal_slots: FxHashMap::default(),
properties: FxHashMap::default(),
symbol_properties: FxHashMap::default(),
prototype: Value::null(),
state: None,
extensible: true,
}
Expand All @@ -144,8 +148,7 @@ impl Object {
// TODO: proto should be a &Value here
pub fn create(proto: Value) -> Self {
let mut obj = Self::default();
obj.internal_slots
.insert(INSTANCE_PROTOTYPE.to_string(), proto);
obj.prototype = proto;
obj
}

Expand All @@ -156,6 +159,7 @@ impl Object {
internal_slots: FxHashMap::default(),
properties: FxHashMap::default(),
symbol_properties: FxHashMap::default(),
prototype: Value::null(),
state: None,
extensible: true,
}
Expand All @@ -168,6 +172,7 @@ impl Object {
internal_slots: FxHashMap::default(),
properties: FxHashMap::default(),
symbol_properties: FxHashMap::default(),
prototype: Value::null(),
state: None,
extensible: true,
}
Expand All @@ -183,6 +188,7 @@ impl Object {
internal_slots: FxHashMap::default(),
properties: FxHashMap::default(),
symbol_properties: FxHashMap::default(),
prototype: Value::null(),
state: None,
extensible: true,
}
Expand All @@ -195,6 +201,7 @@ impl Object {
internal_slots: FxHashMap::default(),
properties: FxHashMap::default(),
symbol_properties: FxHashMap::default(),
prototype: Value::null(),
state: None,
extensible: true,
}
Expand Down Expand Up @@ -419,6 +426,10 @@ impl Object {
pub fn state_mut(&mut self) -> &mut Option<InternalStateCell> {
&mut self.state
}

pub fn prototype(&self) -> &Value {
&self.prototype
}
}

/// Create a new object.
Expand Down Expand Up @@ -476,14 +487,16 @@ pub fn is(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
/// Get the `prototype` of an object.
pub fn get_prototype_of(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
let obj = args.get(0).expect("Cannot get object");
Ok(obj.get_field(INSTANCE_PROTOTYPE))
Ok(obj
.as_object()
.map_or_else(Value::undefined, |object| object.prototype.clone()))
}

/// Set the `prototype` of an object.
pub fn set_prototype_of(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
let obj = args.get(0).expect("Cannot get object").clone();
let proto = args.get(1).expect("Cannot get object").clone();
obj.set_internal_slot(INSTANCE_PROTOTYPE, proto);
obj.as_object_mut().unwrap().prototype = proto;
Ok(obj)
}

Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/string/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fn generic_concat() {
assert_eq!(a, "100 - 50 = 50");
}

#[allow(clippy::result_unwrap_used)]
#[allow(clippy::unwrap_used)]
#[test]
/// Test the correct type is returned from call and construct
fn construct_and_call() {
Expand Down
7 changes: 7 additions & 0 deletions boa/src/builtins/value/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ impl From<Object> for Value {
}
}

impl From<GcObject> for Value {
fn from(object: GcObject) -> Self {
let _timer = BoaProfiler::global().start_event("From<GcObject>", "value");
Value::Object(object)
}
}

#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct TryFromObjectError;

Expand Down
26 changes: 18 additions & 8 deletions boa/src/builtins/value/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,24 @@ macro_rules! print_obj_value {
}
};
(internals of $obj:expr, $display_fn:ident, $indent:expr, $encounters:expr) => {
print_obj_value!(impl internal_slots, $obj, |(key, val)| {
format!(
"{:>width$}: {}",
key,
$display_fn(&val, $encounters, $indent.wrapping_add(4), true),
width = $indent,
)
})
{
let object = $obj.borrow();
if object.prototype().is_object() {
vec![format!(
"{:>width$}: {}",
"__proto__",
$display_fn(object.prototype(), $encounters, $indent.wrapping_add(4), true),
width = $indent,
)]
} else {
vec![format!(
"{:>width$}: {}",
"__proto__",
object.prototype(),
width = $indent,
)]
}
}
};
(props of $obj:expr, $display_fn:ident, $indent:expr, $encounters:expr, $print_internals:expr) => {
print_obj_value!(impl properties, $obj, |(key, val)| {
Expand Down
16 changes: 3 additions & 13 deletions boa/src/builtins/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ pub use crate::builtins::value::val_type::Type;

use crate::builtins::{
function::Function,
object::{
GcObject, InternalState, InternalStateCell, Object, ObjectData, INSTANCE_PROTOTYPE,
PROTOTYPE,
},
object::{GcObject, InternalState, InternalStateCell, Object, ObjectData, PROTOTYPE},
property::Property,
BigInt, Symbol,
};
Expand Down Expand Up @@ -176,11 +173,7 @@ impl Value {
pub fn new_object_from_prototype(proto: Value, data: ObjectData) -> Self {
let mut object = Object::default();
object.data = data;

object
.internal_slots_mut()
.insert(INSTANCE_PROTOTYPE.to_string(), proto);

object.prototype = proto;
Self::object(object)
}

Expand Down Expand Up @@ -493,10 +486,7 @@ impl Value {
let object = object.borrow();
match object.properties().get(field) {
Some(value) => Some(value.clone()),
None => object
.internal_slots()
.get(INSTANCE_PROTOTYPE)
.and_then(|value| value.get_property(field)),
None => object.prototype().get_property(field),
}
}
_ => None,
Expand Down
Loading

0 comments on commit ba450bc

Please sign in to comment.