Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Object internal object methods to GcObject #835

Merged
merged 1 commit into from
Oct 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions boa/src/builtins/array/array_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl ArrayIterator {
let array_iterator = Value::new_object(Some(ctx.global_object()));
array_iterator.set_data(ObjectData::ArrayIterator(Self::new(array, kind)));
array_iterator
.as_object_mut()
.as_object()
.expect("array iterator object")
.set_prototype_instance(ctx.iterator_prototypes().array_iterator().into());
Ok(array_iterator)
Expand Down Expand Up @@ -126,7 +126,7 @@ impl ArrayIterator {
let array_iterator = Value::new_object(Some(global));
make_builtin_fn(Self::next, "next", &array_iterator, 0, ctx);
array_iterator
.as_object_mut()
.as_object()
.expect("array iterator prototype object")
.set_prototype_instance(iterator_prototype);

Expand Down
6 changes: 3 additions & 3 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ impl Array {
None => context.standard_objects().array_object().prototype(),
};

this.as_object_mut()
this.as_object()
.expect("this should be an array object")
.set_prototype_instance(prototype.into());
// This value is used by console.log and other routines to match Object type
Expand All @@ -213,7 +213,7 @@ impl Array {
));
array.set_data(ObjectData::Array);
array
.as_object_mut()
.as_object()
.expect("array object")
.set_prototype_instance(context.standard_objects().array_object().prototype().into());
array.set_field("length", Value::from(0));
Expand Down Expand Up @@ -281,7 +281,7 @@ impl Array {
_interpreter: &mut Context,
) -> Result<Value> {
match args.get(0).and_then(|x| x.as_object()) {
Some(object) => Ok(Value::from(object.is_array())),
Some(object) => Ok(Value::from(object.borrow().is_array())),
None => Ok(Value::from(false)),
}
}
Expand Down
6 changes: 1 addition & 5 deletions boa/src/builtins/boolean/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,7 @@ fn instances_have_correct_proto_set() {
let bool_prototype = forward_val(&mut engine, "boolProto").expect("value expected");

assert!(same_value(
&bool_instance
.as_object()
.unwrap()
.prototype_instance()
.clone(),
&bool_instance.as_object().unwrap().prototype_instance(),
&bool_prototype
));
}
61 changes: 3 additions & 58 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, BuiltIn},
environment::lexical_environment::Environment,
object::{ConstructorBuilder, FunctionBuilder, Object, ObjectData, PROTOTYPE},
object::{ConstructorBuilder, FunctionBuilder, GcObject, Object, ObjectData},
property::{Attribute, DataDescriptor},
syntax::ast::node::{FormalParameter, RcStatementList},
BoaProfiler, Context, Result, Value,
Expand Down Expand Up @@ -172,7 +172,7 @@ impl Function {
/// <https://tc39.es/ecma262/#sec-createunmappedargumentsobject>
pub fn create_unmapped_arguments_object(arguments_list: &[Value]) -> Value {
let len = arguments_list.len();
let mut obj = Object::default();
let mut obj = GcObject::new(Object::default());
// Set length
let length = DataDescriptor::new(
len,
Expand All @@ -195,61 +195,6 @@ pub fn create_unmapped_arguments_object(arguments_list: &[Value]) -> Value {
Value::from(obj)
}

/// Creates a new constructor function
///
/// This utility function handling linking the new Constructor to the prototype.
/// So far this is only used by internal functions
pub fn make_constructor_fn(
name: &str,
length: usize,
body: NativeFunction,
global: &Value,
prototype: Value,
constructable: bool,
callable: bool,
) -> Value {
let _timer =
BoaProfiler::global().start_event(&format!("make_constructor_fn: {}", name), "init");

// Create the native function
let function = Function::BuiltIn(
body.into(),
FunctionFlags::from_parameters(callable, constructable),
);

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

let length = DataDescriptor::new(
length,
Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT,
);
constructor.insert("length", length);

let name = DataDescriptor::new(
name,
Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT,
);
constructor.insert("name", name);

let constructor = Value::from(constructor);

prototype.as_object_mut().unwrap().insert_property(
"constructor",
constructor.clone(),
Attribute::all(),
);

constructor
.as_object_mut()
.expect("constructor object")
.insert_property(PROTOTYPE, prototype, Attribute::all());

constructor
}

/// Creates a new member function of a `Object` or `prototype`.
///
/// A function registered using this macro can then be called from Javascript using:
Expand Down Expand Up @@ -290,7 +235,7 @@ pub fn make_builtin_fn<N>(
function.insert_property("length", length, Attribute::all());

parent
.as_object_mut()
.as_object()
.unwrap()
.insert_property(name, function, Attribute::all());
}
Expand Down
8 changes: 4 additions & 4 deletions boa/src/builtins/iterable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ impl IteratorPrototypes {
let iterator_prototype = create_iterator_prototype(ctx);
Self {
iterator_prototype: iterator_prototype
.as_gc_object()
.as_object()
.expect("Iterator prototype is not an object"),
array_iterator: ArrayIterator::create_prototype(ctx, iterator_prototype.clone())
.as_gc_object()
.as_object()
.expect("Array Iterator Prototype is not an object"),
string_iterator: StringIterator::create_prototype(ctx, iterator_prototype.clone())
.as_gc_object()
.as_object()
.expect("String Iterator Prototype is not an object"),
map_iterator: MapIterator::create_prototype(ctx, iterator_prototype)
.as_gc_object()
.as_object()
.expect("Map Iterator Prototype is not an object"),
}
}
Expand Down
2 changes: 2 additions & 0 deletions boa/src/builtins/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ impl Json {
.map(|obj| {
let object_to_return = Value::new_object(None);
for (key, val) in obj
.borrow()
.iter()
// FIXME: handle accessor descriptors
.map(|(k, v)| (k, v.as_data_descriptor().unwrap().value()))
Expand All @@ -176,6 +177,7 @@ impl Json {
.ok_or_else(Value::undefined)?
} else if replacer_as_object.is_array() {
let mut obj_to_return = serde_json::Map::new();
let replacer_as_object = replacer_as_object.borrow();
let fields = replacer_as_object.keys().filter_map(|key| {
if key == "length" {
None
Expand Down
6 changes: 2 additions & 4 deletions boa/src/builtins/json/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,14 +279,12 @@ fn json_parse_sets_prototypes() {
.unwrap()
.as_object()
.unwrap()
.prototype_instance()
.clone();
.prototype_instance();
let array_prototype = forward_val(&mut engine, r#"jsonObj.arr"#)
.unwrap()
.as_object()
.unwrap()
.prototype_instance()
.clone();
.prototype_instance();
let global_object_prototype = engine
.global_object()
.get_field("Object")
Expand Down
4 changes: 2 additions & 2 deletions boa/src/builtins/map/map_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl MapIterator {
let map_iterator = Value::new_object(Some(ctx.global_object()));
map_iterator.set_data(ObjectData::MapIterator(Self::new(map, kind)));
map_iterator
.as_object_mut()
.as_object()
.expect("map iterator object")
.set_prototype_instance(ctx.iterator_prototypes().map_iterator().into());
Ok(map_iterator)
Expand Down Expand Up @@ -143,7 +143,7 @@ impl MapIterator {
let map_iterator = Value::new_object(Some(global));
make_builtin_fn(Self::next, "next", &map_iterator, 0, ctx);
map_iterator
.as_object_mut()
.as_object()
.expect("map iterator prototype object")
.set_prototype_instance(iterator_prototype);

Expand Down
4 changes: 2 additions & 2 deletions boa/src/builtins/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl Map {
// Set Prototype
let prototype = ctx.global_object().get_field("Map").get_field(PROTOTYPE);

this.as_object_mut()
this.as_object()
.expect("this is map object")
.set_prototype_instance(prototype);
// This value is used by console.log and other routines to match Object type
Expand Down Expand Up @@ -354,7 +354,7 @@ impl Map {
/// Helper function to get a key-value pair from an array.
fn get_key_value(value: &Value) -> Option<(Value, Value)> {
if let Value::Object(object) = value {
if object.borrow().is_array() {
if object.is_array() {
let (key, value) = match value.get_field("length").as_number().unwrap() as i32 {
0 => (Value::Undefined, Value::Undefined),
1 => (value.get_field("0"), Value::Undefined),
Expand Down
46 changes: 23 additions & 23 deletions boa/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl Object {
if let Some(key) = args.get(1) {
let key = key.to_property_key(ctx)?;

if let Some(desc) = object.borrow().get_own_property(&key) {
if let Some(desc) = object.get_own_property(&key) {
return Ok(Self::from_property_descriptor(desc, ctx)?);
}
}
Expand Down Expand Up @@ -169,7 +169,6 @@ impl Object {
for key in object.borrow().keys() {
let descriptor = {
let desc = object
.borrow()
.get_own_property(&key)
.expect("Expected property to be on object.");
Self::from_property_descriptor(desc, ctx)?
Expand Down Expand Up @@ -239,16 +238,16 @@ impl Object {
/// Get the `prototype` of an object.
pub fn get_prototype_of(_: &Value, args: &[Value], _: &mut Context) -> Result<Value> {
let obj = args.get(0).expect("Cannot get object");
Ok(obj.as_object().map_or_else(Value::undefined, |object| {
object.prototype_instance().clone()
}))
Ok(obj
.as_object()
.map_or_else(Value::undefined, |object| object.prototype_instance()))
}

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

Expand Down Expand Up @@ -281,11 +280,11 @@ impl Object {
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties
pub fn define_properties(_: &Value, args: &[Value], ctx: &mut Context) -> Result<Value> {
let arg = args.get(0).cloned().unwrap_or_default();
let arg_obj = arg.as_object_mut();
let arg_obj = arg.as_object();
if let Some(mut obj) = arg_obj {
let props = args.get(1).cloned().unwrap_or_else(Value::undefined);
obj.define_properties(props, ctx)?;
Ok(arg.clone())
Ok(arg)
} else {
ctx.throw_type_error("Expected an object")
}
Expand All @@ -307,19 +306,21 @@ impl Object {
} else if this.is_null() {
Ok("[object Null]".into())
} else {
let gc_o = this.to_object(ctx)?;
let o = gc_o.borrow();
let builtin_tag = match &o.data {
ObjectData::Array => "Array",
// TODO: Arguments Exotic Objects are currently not supported
ObjectData::Function(_) => "Function",
ObjectData::Error => "Error",
ObjectData::Boolean(_) => "Boolean",
ObjectData::Number(_) => "Number",
ObjectData::String(_) => "String",
ObjectData::Date(_) => "Date",
ObjectData::RegExp(_) => "RegExp",
_ => "Object",
let o = this.to_object(ctx)?;
let builtin_tag = {
let o = o.borrow();
match &o.data {
ObjectData::Array => "Array",
// TODO: Arguments Exotic Objects are currently not supported
ObjectData::Function(_) => "Function",
ObjectData::Error => "Error",
ObjectData::Boolean(_) => "Boolean",
ObjectData::Number(_) => "Number",
ObjectData::String(_) => "String",
ObjectData::Date(_) => "Date",
ObjectData::RegExp(_) => "RegExp",
_ => "Object",
}
};

let tag = o.get(&ctx.well_known_symbols().to_string_tag_symbol().into());
Expand Down Expand Up @@ -349,7 +350,6 @@ impl Object {
};
let own_property = this
.as_object()
.as_deref()
.expect("Cannot get THIS object")
.get_own_property(&prop.expect("cannot get prop").into());
if own_property.is_none() {
Expand All @@ -370,7 +370,7 @@ impl Object {
};

let key = key.to_property_key(ctx)?;
let own_property = this.to_object(ctx)?.borrow().get_own_property(&key);
let own_property = this.to_object(ctx)?.get_own_property(&key);

Ok(own_property.map_or(Value::from(false), |own_prop| {
Value::from(own_prop.enumerable())
Expand Down
5 changes: 5 additions & 0 deletions boa/src/builtins/regexp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ impl RegExp {
.to_string(ctx)?;
let mut last_index = this.get_field("lastIndex").to_index(ctx)?;
let result = if let Some(object) = this.as_object() {
let object = object.borrow();
let regex = object.as_regexp().unwrap();
let result =
if let Some(m) = regex.matcher.find_from(arg_str.as_str(), last_index).next() {
Expand Down Expand Up @@ -349,6 +350,7 @@ impl RegExp {
.to_string(ctx)?;
let mut last_index = this.get_field("lastIndex").to_index(ctx)?;
let result = if let Some(object) = this.as_object() {
let object = object.borrow();
let regex = object.as_regexp().unwrap();
let result = {
if let Some(m) = regex.matcher.find_from(arg_str.as_str(), last_index).next() {
Expand Down Expand Up @@ -401,6 +403,7 @@ impl RegExp {
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@match
pub(crate) fn r#match(this: &Value, arg: RcString, ctx: &mut Context) -> Result<Value> {
let (matcher, flags) = if let Some(object) = this.as_object() {
let object = object.borrow();
let regex = object.as_regexp().unwrap();
(regex.matcher.clone(), regex.flags.clone())
} else {
Expand Down Expand Up @@ -433,6 +436,7 @@ impl RegExp {
#[allow(clippy::wrong_self_convention)]
pub(crate) fn to_string(this: &Value, _: &[Value], context: &mut Context) -> Result<Value> {
let (body, flags) = if let Some(object) = this.as_object() {
let object = object.borrow();
let regex = object.as_regexp().unwrap();
(regex.original_source.clone(), regex.flags.clone())
} else {
Expand All @@ -457,6 +461,7 @@ impl RegExp {
// TODO: it's returning an array, it should return an iterator
pub(crate) fn match_all(this: &Value, arg_str: String) -> Result<Value> {
let matches = if let Some(object) = this.as_object() {
let object = object.borrow();
let regex = object.as_regexp().unwrap();
let mut matches = Vec::new();

Expand Down
4 changes: 2 additions & 2 deletions boa/src/builtins/string/string_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl StringIterator {
let string_iterator = Value::new_object(Some(ctx.global_object()));
string_iterator.set_data(ObjectData::StringIterator(Self::new(string)));
string_iterator
.as_object_mut()
.as_object()
.expect("array iterator object")
.set_prototype_instance(ctx.iterator_prototypes().string_iterator().into());
Ok(string_iterator)
Expand Down Expand Up @@ -76,7 +76,7 @@ impl StringIterator {
let array_iterator = Value::new_object(Some(global));
make_builtin_fn(Self::next, "next", &array_iterator, 0, ctx);
array_iterator
.as_object_mut()
.as_object()
.expect("array iterator prototype object")
.set_prototype_instance(iterator_prototype);

Expand Down
Loading