From a5d41ffca2ea868bd95f8abb1c1685a33d9571f8 Mon Sep 17 00:00:00 2001 From: Rohit Kumar Date: Thu, 17 Oct 2019 00:44:50 +0530 Subject: [PATCH] handle array case when setting objects --- src/lib/exec.rs | 38 +++++++++++++++++++++++++++++++++++--- src/lib/js/object.rs | 2 +- src/lib/js/value.rs | 11 +++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/lib/exec.rs b/src/lib/exec.rs index 65040dd33bc..7cef96bf47a 100644 --- a/src/lib/exec.rs +++ b/src/lib/exec.rs @@ -400,10 +400,11 @@ impl Executor for Interpreter { ExprDef::GetField(ref obj, ref field) => { let val_obj = self.run(obj)?; let val_field = self.run(field)?; - // TODO: handle array case - val_obj.borrow().set_field(val_field.to_string(), val.clone()); + val_obj + .borrow() + .set_field(val_field.to_string(), val.clone()); } - _ => () + _ => (), } Ok(val) } @@ -691,4 +692,35 @@ mod tests { "#; assert_eq!(exec(scenario), String::from("22")); } + + #[test] + fn array_field_set() { + let element_changes = r#" + let m = [1, 2, 3]; + m[1] = 5; + m[1] + "#; + assert_eq!(exec(element_changes), String::from("5")); + + let length_changes = r#" + let m = [1, 2, 3]; + m[10] = 52; + m.length + "#; + assert_eq!(exec(length_changes), String::from("11")); + + let negative_index_wont_affect_length = r#" + let m = [1, 2, 3]; + m[-11] = 5; + m.length + "#; + assert_eq!(exec(negative_index_wont_affect_length), String::from("3")); + + let non_num_key_wont_affect_length = r#" + let m = [1, 2, 3]; + m["magic"] = 5; + m.length + "#; + assert_eq!(exec(non_num_key_wont_affect_length), String::from("3")); + } } diff --git a/src/lib/js/object.rs b/src/lib/js/object.rs index 4228aeb75e8..eb5aba85752 100644 --- a/src/lib/js/object.rs +++ b/src/lib/js/object.rs @@ -402,7 +402,7 @@ impl Object { } } -#[derive(Trace, Finalize, Clone, Debug)] +#[derive(Trace, Finalize, Clone, Debug, Eq, PartialEq)] pub enum ObjectKind { Function, Array, diff --git a/src/lib/js/value.rs b/src/lib/js/value.rs index 711895f8b72..0abb86123a8 100644 --- a/src/lib/js/value.rs +++ b/src/lib/js/value.rs @@ -402,6 +402,17 @@ impl ValueData { pub fn set_field(&self, field: String, val: Value) -> Value { match *self { ValueData::Object(ref obj) => { + if obj.borrow().kind == ObjectKind::Array { + if let Ok(num) = field.parse::() { + if num > 0 { + let len: i32 = from_value(self.get_field_slice("length")) + .expect("Could not convert argument to i32"); + if len < (num + 1) as i32 { + self.set_field_slice("length", to_value(num + 1)); + } + } + } + } obj.borrow_mut() .properties .insert(field, Property::default().value(val.clone()));