Skip to content

Commit

Permalink
Add receiver parameter to object internal methods (#1042)
Browse files Browse the repository at this point in the history
Co-authored-by: tofpie <tofpie@users.noreply.github.com>
  • Loading branch information
tofpie and tofpie authored Jan 7, 2021
1 parent e8bc79c commit 1a7e832
Show file tree
Hide file tree
Showing 12 changed files with 294 additions and 113 deletions.
45 changes: 23 additions & 22 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,17 +144,13 @@ impl Array {
let array = Array::array_create(this, 0, Some(prototype), context)?;

if !length.is_number() {
array.set_field(0, Value::from(length), context)?;
array.set_field("length", Value::from(1), context)?;
array.set_property(0, DataDescriptor::new(length, Attribute::all()));
array.set_field("length", 1, context)?;
} else {
if length.is_double() {
return context.throw_range_error("Invalid array length");
}
array.set_field(
"length",
Value::from(length.to_u32(context).unwrap()),
context,
)?;
array.set_field("length", length.to_u32(context).unwrap(), context)?;
}

Ok(array)
Expand All @@ -176,7 +172,7 @@ impl Array {
let array = Array::array_create(this, items_len, Some(prototype), context)?;

for (k, item) in items.iter().enumerate() {
array.set_field(k, item.clone(), context)?;
array.set_property(k, DataDescriptor::new(item.clone(), Attribute::all()));
}

Ok(array)
Expand Down Expand Up @@ -256,7 +252,7 @@ impl Array {
array_obj_ptr.set_property("length".to_string(), length);

for (n, value) in array_contents.iter().enumerate() {
array_obj_ptr.set_field(n, value, context)?;
array_obj_ptr.set_property(n, DataDescriptor::new(value, Attribute::all()));
}
Ok(array_obj_ptr)
}
Expand All @@ -272,7 +268,7 @@ impl Array {

for (n, value) in add_values.iter().enumerate() {
let new_index = orig_length.wrapping_add(n);
array_ptr.set_field(new_index, value, context)?;
array_ptr.set_property(new_index, DataDescriptor::new(value, Attribute::all()));
}

array_ptr.set_field(
Expand Down Expand Up @@ -511,13 +507,13 @@ impl Array {
let lower_value = this.get_field(lower, context)?;

if upper_exists && lower_exists {
this.set_field(upper, lower_value, context)?;
this.set_field(lower, upper_value, context)?;
this.set_property(upper, DataDescriptor::new(lower_value, Attribute::all()));
this.set_property(lower, DataDescriptor::new(upper_value, Attribute::all()));
} else if upper_exists {
this.set_field(lower, upper_value, context)?;
this.set_property(lower, DataDescriptor::new(upper_value, Attribute::all()));
this.remove_property(upper);
} else if lower_exists {
this.set_field(upper, lower_value, context)?;
this.set_property(upper, DataDescriptor::new(lower_value, Attribute::all()));
this.remove_property(lower);
}
}
Expand Down Expand Up @@ -553,7 +549,7 @@ impl Array {
if from_value.is_undefined() {
this.remove_property(to);
} else {
this.set_field(to, from_value, context)?;
this.set_property(to, DataDescriptor::new(from_value, Attribute::all()));
}
}

Expand Down Expand Up @@ -590,15 +586,17 @@ impl Array {
if from_value.is_undefined() {
this.remove_property(to);
} else {
this.set_field(to, from_value, context)?;
this.set_property(to, DataDescriptor::new(from_value, Attribute::all()));
}
}
for j in 0..arg_c {
this.set_field(
this.set_property(
j,
args.get(j).expect("Could not get argument").clone(),
context,
)?;
DataDescriptor::new(
args.get(j).expect("Could not get argument").clone(),
Attribute::all(),
),
);
}
}

Expand Down Expand Up @@ -905,7 +903,7 @@ impl Array {
let fin = Self::get_relative_end(context, args.get(2), len)?;

for i in start..fin {
this.set_field(i, value.clone(), context)?;
this.set_property(i, DataDescriptor::new(value.clone(), Attribute::all()));
}

Ok(this.clone())
Expand Down Expand Up @@ -968,7 +966,10 @@ impl Array {
}
let mut new_array_len: i32 = 0;
for i in from..from.saturating_add(span) {
new_array.set_field(new_array_len, this.get_field(i, context)?, context)?;
new_array.set_property(
new_array_len,
DataDescriptor::new(this.get_field(i, context)?, Attribute::all()),
);
new_array_len = new_array_len.saturating_add(1);
}
new_array.set_field("length", Value::from(new_array_len), context)?;
Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ pub fn create_unmapped_arguments_object(arguments_list: &[Value]) -> Value {
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::PERMANENT,
);
// Define length as a property
obj.define_own_property("length", length.into());
obj.ordinary_define_own_property("length", length.into());
let mut index: usize = 0;
while index < len {
let val = arguments_list.get(index).expect("Could not get argument");
Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ impl Json {
.map(|obj| {
let object_to_return = Value::object(Object::default());
for key in obj.borrow().keys() {
let val = obj.get(&key, context)?;
let val = obj.get(&key, obj.clone().into(), context)?;
let this_arg = object.clone();
object_to_return.set_property(
key.to_owned(),
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ impl Object {
let status = obj
.as_object()
.expect("obj was not an object")
.set_prototype_instance(proto);
.set_prototype_of(proto);

// 5. If status is false, throw a TypeError exception.
if !status {
Expand Down Expand Up @@ -413,6 +413,7 @@ impl Object {

let tag = o.get(
&context.well_known_symbols().to_string_tag_symbol().into(),
o.clone().into(),
context,
)?;

Expand Down
11 changes: 8 additions & 3 deletions boa/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,9 +531,14 @@ impl Context {
Function::BuiltIn(body.into(), FunctionFlags::CALLABLE),
function_prototype,
));
function.set(PROTOTYPE.into(), proto, self)?;
function.set("length".into(), length.into(), self)?;
function.set("name".into(), name.into(), self)?;
function.set(PROTOTYPE.into(), proto, function.clone().into(), self)?;
function.set(
"length".into(),
length.into(),
function.clone().into(),
self,
)?;
function.set("name".into(), name.into(), function.clone().into(), self)?;

Ok(function)
}
Expand Down
32 changes: 22 additions & 10 deletions boa/src/object/gcobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ impl GcObject {
// prototype as prototype for the new object
// see <https://tc39.es/ecma262/#sec-ordinarycreatefromconstructor>
// see <https://tc39.es/ecma262/#sec-getprototypefromconstructor>
let proto = self.get(&PROTOTYPE.into(), context)?;
let proto = self.get(&PROTOTYPE.into(), self.clone().into(), context)?;
let proto = if proto.is_object() {
proto
} else {
Expand Down Expand Up @@ -408,36 +408,45 @@ impl GcObject {
let mut attribute = Attribute::empty();

let enumerable_key = PropertyKey::from("enumerable");
if self.has_property(&enumerable_key) && self.get(&enumerable_key, context)?.to_boolean() {
if self.has_property(&enumerable_key)
&& self
.get(&enumerable_key, self.clone().into(), context)?
.to_boolean()
{
attribute |= Attribute::ENUMERABLE;
}

let configurable_key = PropertyKey::from("configurable");
if self.has_property(&configurable_key)
&& self.get(&configurable_key, context)?.to_boolean()
&& self
.get(&configurable_key, self.clone().into(), context)?
.to_boolean()
{
attribute |= Attribute::CONFIGURABLE;
}

let mut value = None;
let value_key = PropertyKey::from("value");
if self.has_property(&value_key) {
value = Some(self.get(&value_key, context)?);
value = Some(self.get(&value_key, self.clone().into(), context)?);
}

let mut has_writable = false;
let writable_key = PropertyKey::from("writable");
if self.has_property(&writable_key) {
has_writable = true;
if self.get(&writable_key, context)?.to_boolean() {
if self
.get(&writable_key, self.clone().into(), context)?
.to_boolean()
{
attribute |= Attribute::WRITABLE;
}
}

let mut get = None;
let get_key = PropertyKey::from("get");
if self.has_property(&get_key) {
let getter = self.get(&get_key, context)?;
let getter = self.get(&get_key, self.clone().into(), context)?;
match getter {
Value::Object(ref object) if object.is_callable() => {
get = Some(object.clone());
Expand All @@ -453,7 +462,7 @@ impl GcObject {
let mut set = None;
let set_key = PropertyKey::from("set");
if self.has_property(&set_key) {
let setter = self.get(&set_key, context)?;
let setter = self.get(&set_key, self.clone().into(), context)?;
match setter {
Value::Object(ref object) if object.is_callable() => {
set = Some(object.clone());
Expand Down Expand Up @@ -709,7 +718,7 @@ impl GcObject {
K: Into<PropertyKey>,
{
let key = key.into();
let value = self.get(&key, context)?;
let value = self.get(&key, self.clone().into(), context)?;

if value.is_null_or_undefined() {
return Ok(None);
Expand Down Expand Up @@ -743,7 +752,10 @@ impl GcObject {
// Return ? InstanceofOperator(O, BC).

if let Some(object) = value.as_object() {
if let Some(prototype) = self.get(&"prototype".into(), context)?.as_object() {
if let Some(prototype) = self
.get(&"prototype".into(), self.clone().into(), context)?
.as_object()
{
let mut object = object.get_prototype_of();
while let Some(object_prototype) = object.as_object() {
if GcObject::equals(&prototype, &object_prototype) {
Expand Down Expand Up @@ -791,7 +803,7 @@ impl GcObject {
let key = key.into();
let desc = desc.into();

let success = self.define_own_property(key.clone(), desc);
let success = self.define_own_property(key.clone(), desc, context)?;
if !success {
Err(context.construct_type_error(format!("Cannot redefine property: {}", key)))
} else {
Expand Down
Loading

0 comments on commit 1a7e832

Please sign in to comment.