Fixed get_keys with prototypes

This commit is contained in:
Nathan Adams 2019-11-27 22:30:01 +01:00
parent 585c520b87
commit 2650433271
3 changed files with 15 additions and 6 deletions

View File

@ -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<dyn Object<'gc> + '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<String>;
fn get_keys(&self) -> HashSet<String>;
/// Coerce the object into a string.
fn as_string(&self) -> String;

View File

@ -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<String> {
fn get_keys(&self) -> HashSet<String> {
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 {

View File

@ -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<String> = 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();