Skip to content

Commit

Permalink
Change type of object prototypes to Option<JsObject>
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Oct 6, 2021
1 parent 45c8fa0 commit 9cb53e7
Show file tree
Hide file tree
Showing 22 changed files with 157 additions and 166 deletions.
2 changes: 1 addition & 1 deletion boa/src/builtins/array_buffer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ impl ArrayBuffer {
context,
)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
obj.set_prototype(prototype.into());

// 2. Let block be ? CreateByteDataBlock(byteLength).
// TODO: for now just a arbitrary limit to not OOM.
Expand Down
10 changes: 5 additions & 5 deletions boa/src/builtins/boolean/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{forward, forward_val, Context, JsValue};
use crate::{forward, forward_val, Context};

/// Test the correct type is returned from call and construct
#[allow(clippy::unwrap_used)]
Expand Down Expand Up @@ -58,8 +58,8 @@ fn instances_have_correct_proto_set() {
let bool_instance = forward_val(&mut context, "boolInstance").expect("value expected");
let bool_prototype = forward_val(&mut context, "boolProto").expect("value expected");

assert!(JsValue::same_value(
&bool_instance.as_object().unwrap().prototype_instance(),
&bool_prototype
));
assert_eq!(
&*bool_instance.as_object().unwrap().prototype(),
&bool_prototype.as_object()
);
}
1 change: 0 additions & 1 deletion boa/src/builtins/console/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,6 @@ impl Console {
LogMessage::Info(display_obj(args.get_or_undefined(0), true)),
context.console(),
);

Ok(JsValue::undefined())
}
}
2 changes: 1 addition & 1 deletion boa/src/builtins/error/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl BuiltIn for EvalError {
)
.name(Self::NAME)
.length(Self::LENGTH)
.inherit(error_prototype.into())
.inherit(error_prototype)
.property("name", Self::NAME, attribute)
.property("message", "", attribute)
.build();
Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/error/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl BuiltIn for RangeError {
)
.name(Self::NAME)
.length(Self::LENGTH)
.inherit(error_prototype.into())
.inherit(error_prototype)
.property("name", Self::NAME, attribute)
.property("message", "", attribute)
.build();
Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/error/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl BuiltIn for ReferenceError {
)
.name(Self::NAME)
.length(Self::LENGTH)
.inherit(error_prototype.into())
.inherit(error_prototype)
.property("name", Self::NAME, attribute)
.property("message", "", attribute)
.build();
Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/error/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl BuiltIn for SyntaxError {
)
.name(Self::NAME)
.length(Self::LENGTH)
.inherit(error_prototype.into())
.inherit(error_prototype)
.property("name", Self::NAME, attribute)
.property("message", "", attribute)
.build();
Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/error/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl BuiltIn for TypeError {
)
.name(Self::NAME)
.length(Self::LENGTH)
.inherit(error_prototype.into())
.inherit(error_prototype)
.property("name", Self::NAME, attribute)
.property("message", "", attribute)
.build();
Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/error/uri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl BuiltIn for UriError {
)
.name(Self::NAME)
.length(Self::LENGTH)
.inherit(error_prototype.into())
.inherit(error_prototype)
.property("name", Self::NAME, attribute)
.property("message", "", attribute)
.build();
Expand Down
23 changes: 9 additions & 14 deletions boa/src/builtins/json/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{forward, forward_val, Context, JsValue};
use crate::{forward, forward_val, Context};

#[test]
fn json_sanity() {
Expand Down Expand Up @@ -413,27 +413,22 @@ fn json_parse_sets_prototypes() {
.unwrap()
.as_object()
.unwrap()
.prototype_instance();
.prototype()
.clone();
let array_prototype = forward_val(&mut context, r#"jsonObj.arr"#)
.unwrap()
.as_object()
.unwrap()
.prototype_instance();
let global_object_prototype: JsValue = context
.prototype()
.clone();
let global_object_prototype = context
.standard_objects()
.object_object()
.prototype()
.into();
let global_array_prototype: JsValue =
context.standard_objects().array_object().prototype().into();
assert!(JsValue::same_value(
&object_prototype,
&global_object_prototype
));
assert!(JsValue::same_value(
&array_prototype,
&global_array_prototype
));
let global_array_prototype = context.standard_objects().array_object().prototype().into();
assert_eq!(object_prototype, global_object_prototype);
assert_eq!(array_prototype, global_array_prototype);
}

#[test]
Expand Down
5 changes: 3 additions & 2 deletions boa/src/builtins/object/for_in_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,9 @@ impl ForInIterator {
}
}
}
match object.prototype_instance().to_object(context) {
Ok(o) => {
let proto = object.prototype().clone();
match proto {
Some(o) => {
object = o;
}
_ => {
Expand Down
33 changes: 16 additions & 17 deletions boa/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
},
property::{Attribute, DescriptorKind, PropertyDescriptor, PropertyKey, PropertyNameKind},
symbol::WellKnownSymbols,
value::{JsValue, Type},
value::JsValue,
BoaProfiler, Context, JsResult,
};

Expand Down Expand Up @@ -53,7 +53,7 @@ impl BuiltIn for Object {
)
.name(Self::NAME)
.length(Self::LENGTH)
.inherit(JsValue::null())
.inherit(None)
.method(Self::has_own_property, "hasOwnProperty", 0)
.method(Self::property_is_enumerable, "propertyIsEnumerable", 0)
.method(Self::to_string, "toString", 0)
Expand Down Expand Up @@ -284,7 +284,9 @@ impl Object {
let obj = args[0].clone().to_object(ctx)?;

// 2. Return ? obj.[[GetPrototypeOf]]().
Ok(obj.prototype_instance())
Ok(obj
.__get_prototype_of__(ctx)?
.map_or(JsValue::Null, JsValue::new))
}

/// Set the `prototype` of an object.
Expand All @@ -308,25 +310,22 @@ impl Object {
.require_object_coercible(ctx)?
.clone();

// 2. If Type(proto) is neither Object nor Null, throw a TypeError exception.
let proto = args.get_or_undefined(1);
if !matches!(proto.get_type(), Type::Object | Type::Null) {
return ctx.throw_type_error(format!(
"expected an object or null, got {}",
proto.type_of()
));
}

// 3. If Type(O) is not Object, return O.
if !obj.is_object() {
return Ok(obj);
}
let proto = match args.get_or_undefined(1) {
JsValue::Object(obj) => obj.clone(),
// 3. If Type(O) is not Object, return O.
JsValue::Null => return Ok(JsValue::Null),
// 2. If Type(proto) is neither Object nor Null, throw a TypeError exception.
val => {
return ctx
.throw_type_error(format!("expected an object or null, got {}", val.type_of()))
}
};

// 4. Let status be ? O.[[SetPrototypeOf]](proto).
let status = obj
.as_object()
.expect("obj was not an object")
.__set_prototype_of__(proto.clone(), ctx)?;
.__set_prototype_of__(Some(proto), ctx)?;

// 5. If status is false, throw a TypeError exception.
if !status {
Expand Down
15 changes: 9 additions & 6 deletions boa/src/builtins/reflect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,9 @@ impl Reflect {
.get(0)
.and_then(|v| v.as_object())
.ok_or_else(|| context.construct_type_error("target must be an object"))?;
target.__get_prototype_of__(context)
Ok(target
.__get_prototype_of__(context)?
.map_or(JsValue::Null, JsValue::new))
}

/// Returns `true` if the object has the property, `false` otherwise.
Expand Down Expand Up @@ -377,10 +379,11 @@ impl Reflect {
.get(0)
.and_then(|v| v.as_object())
.ok_or_else(|| context.construct_type_error("target must be an object"))?;
let proto = args.get_or_undefined(1);
if !proto.is_null() && !proto.is_object() {
return context.throw_type_error("proto must be an object or null");
}
Ok(target.__set_prototype_of__(proto.clone(), context)?.into())
let proto = match args.get_or_undefined(1) {
JsValue::Object(obj) => Some(obj.clone()),
JsValue::Null => None,
_ => return context.throw_type_error("proto must be an object or null"),
};
Ok(target.__set_prototype_of__(proto, context)?.into())
}
}
2 changes: 1 addition & 1 deletion boa/src/builtins/typed_array/integer_indexed_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl IntegerIndexed {
a.borrow_mut().data = ObjectData::integer_indexed(data);

// 10. Set A.[[Prototype]] to prototype.
a.set_prototype_instance(prototype.into());
a.set_prototype(prototype.into());

// 11. Return A.
a
Expand Down
4 changes: 2 additions & 2 deletions boa/src/builtins/typed_array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ macro_rules! typed_array {
TypedArrayName::$ty.element_size(),
Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT,
)
.custom_prototype(typed_array_constructor.into())
.inherit(typed_array_constructor_proto.into())
.custom_prototype(typed_array_constructor)
.inherit(typed_array_constructor_proto)
.build()
.into()
}
Expand Down
14 changes: 8 additions & 6 deletions boa/src/environment/function_environment_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
lexical_environment::{Environment, EnvironmentType, VariableScope},
},
gc::{empty_trace, Finalize, Trace},
object::JsObject,
object::{JsObject, ObjectPrototype},
Context, JsResult, JsValue,
};

Expand Down Expand Up @@ -114,21 +114,23 @@ impl FunctionEnvironmentRecord {
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-getsuperbase
pub fn get_super_base(&self) -> JsValue {
pub fn get_super_base(&self, context: &mut Context) -> JsResult<Option<ObjectPrototype>> {
// 1. Let home be envRec.[[FunctionObject]].[[HomeObject]].
let home = &self.home_object;

// 2. If home has the value undefined, return undefined.
if home.is_undefined() {
JsValue::undefined()
Ok(None)
} else {
// 3. Assert: Type(home) is Object.
assert!(home.is_object());

// 4. Return ? home.[[GetPrototypeOf]]().
home.as_object()
.expect("home_object must be an Object")
.prototype_instance()
Ok(Some(
home.as_object()
.expect("home_object must be an Object")
.__get_prototype_of__(context)?,
))
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions boa/src/exec/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,9 +791,12 @@ mod in_operator {
let bar_val = forward_val(&mut context, "bar").unwrap();
let bar_obj = bar_val.as_object().unwrap();
let foo_val = forward_val(&mut context, "Foo").unwrap();
assert!(bar_obj
.prototype_instance()
.strict_equals(&foo_val.get_field("prototype", &mut context).unwrap()));
assert_eq!(
&*bar_obj.prototype(),
&foo_val
.as_object()
.and_then(|obj| obj.get("prototype", &mut context).unwrap().as_object())
);
}
}

Expand Down
Loading

0 comments on commit 9cb53e7

Please sign in to comment.