From 26504332717d50c0728210a96240e597df0d938b Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Wed, 27 Nov 2019 22:30:01 +0100 Subject: [PATCH] Fixed get_keys with prototypes --- core/src/avm1/object.rs | 3 ++- core/src/avm1/script_object.rs | 16 ++++++++++++---- core/tests/regression_tests.rs | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/core/src/avm1/object.rs b/core/src/avm1/object.rs index fc89866a2..f2565fad3 100644 --- a/core/src/avm1/object.rs +++ b/core/src/avm1/object.rs @@ -7,6 +7,7 @@ use crate::avm1::{Avm1, Error, ScriptObject, UpdateContext, Value}; use crate::display_object::DisplayNode; use enumset::EnumSet; use gc_arena::{Collect, GcCell}; +use std::collections::HashSet; use std::fmt::Debug; pub type ObjectCell<'gc> = GcCell<'gc, Box + 'gc>>; @@ -164,7 +165,7 @@ pub trait Object<'gc>: 'gc + Collect + Debug { fn is_property_enumerable(&self, name: &str) -> bool; /// Enumerate the object. - fn get_keys(&self) -> Vec; + fn get_keys(&self) -> HashSet; /// Coerce the object into a string. fn as_string(&self) -> String; diff --git a/core/src/avm1/script_object.rs b/core/src/avm1/script_object.rs index 93962e8d8..dd7691974 100644 --- a/core/src/avm1/script_object.rs +++ b/core/src/avm1/script_object.rs @@ -7,7 +7,7 @@ use core::fmt; use enumset::EnumSet; use gc_arena::{GcCell, MutationContext}; use std::collections::hash_map::Entry; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; pub const TYPE_OF_OBJECT: &str = "object"; pub const TYPE_OF_FUNCTION: &str = "function"; @@ -126,7 +126,7 @@ impl<'gc> ScriptObject<'gc> { p.write(gc_context).define_value( "constructor", Value::Object(function), - EnumSet::empty(), + Attribute::DontEnum.into(), ); function .write(gc_context) @@ -347,7 +347,11 @@ impl<'gc> Object<'gc> for ScriptObject<'gc> { } /// Enumerate the object. - fn get_keys(&self) -> Vec { + fn get_keys(&self) -> HashSet { + let mut result = self + .prototype + .map_or_else(HashSet::new, |p| p.read().get_keys()); + self.values .iter() .filter_map(|(k, p)| { @@ -357,7 +361,11 @@ impl<'gc> Object<'gc> for ScriptObject<'gc> { None } }) - .collect() + .for_each(|k| { + result.insert(k); + }); + + result } fn as_string(&self) -> String { diff --git a/core/tests/regression_tests.rs b/core/tests/regression_tests.rs index 958adcbae..c7bb0164e 100644 --- a/core/tests/regression_tests.rs +++ b/core/tests/regression_tests.rs @@ -72,7 +72,7 @@ swf_tests! { fn test_prototype_enumerate() -> Result<(), Error> { let trace_log = run_swf("tests/swfs/avm1/prototype_enumerate/test.swf", 1)?; let mut actual: Vec = trace_log.lines().map(|s| s.to_string()).collect(); - let mut expected = vec!["a", "b", "c", "d"]; + let mut expected = vec!["a", "b", "c", "d", "e"]; actual.sort(); expected.sort();