Skip to content

Commit

Permalink
handle array case when setting objects
Browse files Browse the repository at this point in the history
  • Loading branch information
letmutx committed Oct 16, 2019
1 parent 37e6eaf commit b79af3a
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 4 deletions.
38 changes: 35 additions & 3 deletions src/lib/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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"));
}
}
2 changes: 1 addition & 1 deletion src/lib/js/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ impl Object {
}
}

#[derive(Trace, Finalize, Clone, Debug)]
#[derive(Trace, Finalize, Clone, Debug, Eq, PartialEq)]
pub enum ObjectKind {
Function,
Array,
Expand Down
11 changes: 11 additions & 0 deletions src/lib/js/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<usize>() {
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()));
Expand Down

0 comments on commit b79af3a

Please sign in to comment.