Skip to content

Commit

Permalink
Merge fd16259 into e82dee1
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat authored Oct 9, 2020
2 parents e82dee1 + fd16259 commit 44ad89a
Show file tree
Hide file tree
Showing 20 changed files with 239 additions and 188 deletions.
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 @@ -101,7 +101,7 @@ impl Array {
// Set Prototype
let prototype = 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 Down Expand Up @@ -150,7 +150,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 @@ -218,7 +218,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
6 changes: 3 additions & 3 deletions boa/src/builtins/iterable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ 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)
.as_gc_object()
.as_object()
.expect("String Iterator Prototype is not an object"),
}
}
Expand Down
6 changes: 4 additions & 2 deletions boa/src/builtins/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,13 @@ impl Json {
let replacer_as_object = replacer
.as_object()
.expect("JSON.stringify replacer was an object");
if replacer_as_object.is_callable() {
if replacer_as_object.borrow().is_callable() {
object
.as_object()
.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 @@ -174,8 +175,9 @@ impl Json {
Ok(Value::from(object_to_return.to_json(ctx)?.to_string()))
})
.ok_or_else(Value::undefined)?
} else if replacer_as_object.is_array() {
} else if replacer_as_object.borrow().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 @@ -270,14 +270,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
2 changes: 1 addition & 1 deletion boa/src/builtins/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,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
43 changes: 22 additions & 21 deletions boa/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,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 @@ -162,11 +162,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 @@ -188,19 +188,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 @@ -230,7 +232,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 @@ -251,7 +252,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
2 changes: 1 addition & 1 deletion boa/src/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
//! class.method("speak", 0, |this, _args, _ctx| {
//! if let Some(object) = this.as_object() {
//! if let Some(animal) = object.downcast_ref::<Animal>() {
//! match animal {
//! match &*animal {
//! Self::Cat => println!("meow"),
//! Self::Dog => println!("woof"),
//! Self::Other => println!(r"¯\_(ツ)_/¯"),
Expand Down
Loading

0 comments on commit 44ad89a

Please sign in to comment.