avm2: Filter traits in `call_instance_xyz` by the trait type before actually getting trait fields.
Fixes the `as3_virtual_properties` test, where the old approach would accidentally grab a `Getter` and then think there's no setter (there is, you just have to look further down the list).
This commit is contained in:
parent
a2cd7443e8
commit
a8fd0622b2
|
@ -746,12 +746,15 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.read()
|
.read()
|
||||||
.lookup_instance_traits(name, &mut class_traits)?;
|
.lookup_instance_traits(name, &mut class_traits)?;
|
||||||
let base_trait = class_traits.first().ok_or_else(|| {
|
let base_trait = class_traits
|
||||||
format!(
|
.iter()
|
||||||
"Attempted to supercall method {:?}, which does not exist",
|
.find(|t| matches!(t.kind(), TraitKind::Method { .. }))
|
||||||
name
|
.ok_or_else(|| {
|
||||||
)
|
format!(
|
||||||
})?;
|
"Attempted to supercall method {:?}, which does not exist",
|
||||||
|
name
|
||||||
|
)
|
||||||
|
})?;
|
||||||
let scope = constr_with_trait.get_scope();
|
let scope = constr_with_trait.get_scope();
|
||||||
|
|
||||||
if let TraitKind::Method { method, .. } = base_trait.kind() {
|
if let TraitKind::Method { method, .. } = base_trait.kind() {
|
||||||
|
@ -765,11 +768,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
||||||
|
|
||||||
callee.call(reciever, arguments, activation, Some(constr_with_trait))
|
callee.call(reciever, arguments, activation, Some(constr_with_trait))
|
||||||
} else {
|
} else {
|
||||||
Err(format!(
|
unreachable!();
|
||||||
"Attempted to supercall method {:?}, which does not exist",
|
|
||||||
name
|
|
||||||
)
|
|
||||||
.into())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -788,7 +787,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
||||||
) -> Result<Value<'gc>, Error> {
|
) -> Result<Value<'gc>, Error> {
|
||||||
let constr_with_trait = self.find_base_constr_for_trait(&name)?.ok_or_else(|| {
|
let constr_with_trait = self.find_base_constr_for_trait(&name)?.ok_or_else(|| {
|
||||||
format!(
|
format!(
|
||||||
"Attempted to supercall method {:?}, which does not exist",
|
"Attempted to supercall getter {:?}, which does not exist",
|
||||||
name
|
name
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
@ -798,12 +797,15 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.read()
|
.read()
|
||||||
.lookup_instance_traits(name, &mut class_traits)?;
|
.lookup_instance_traits(name, &mut class_traits)?;
|
||||||
let base_trait = class_traits.first().ok_or_else(|| {
|
let base_trait = class_traits
|
||||||
format!(
|
.iter()
|
||||||
"Attempted to supercall method {:?}, which does not exist",
|
.find(|t| matches!(t.kind(), TraitKind::Getter { .. }))
|
||||||
name
|
.ok_or_else(|| {
|
||||||
)
|
format!(
|
||||||
})?;
|
"Attempted to supercall getter {:?}, which does not exist",
|
||||||
|
name
|
||||||
|
)
|
||||||
|
})?;
|
||||||
let scope = constr_with_trait.get_scope();
|
let scope = constr_with_trait.get_scope();
|
||||||
|
|
||||||
if let TraitKind::Getter { method, .. } = base_trait.kind() {
|
if let TraitKind::Getter { method, .. } = base_trait.kind() {
|
||||||
|
@ -817,11 +819,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
||||||
|
|
||||||
callee.call(reciever, &[], activation, Some(constr_with_trait))
|
callee.call(reciever, &[], activation, Some(constr_with_trait))
|
||||||
} else {
|
} else {
|
||||||
Err(format!(
|
unreachable!();
|
||||||
"Attempted to supercall getter for {:?}, which does not exist",
|
|
||||||
name
|
|
||||||
)
|
|
||||||
.into())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,7 +839,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let constr_with_trait = self.find_base_constr_for_trait(&name)?.ok_or_else(|| {
|
let constr_with_trait = self.find_base_constr_for_trait(&name)?.ok_or_else(|| {
|
||||||
format!(
|
format!(
|
||||||
"Attempted to supercall method {:?}, which does not exist",
|
"Attempted to supercall setter {:?}, which does not exist",
|
||||||
name
|
name
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
@ -851,12 +849,15 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.read()
|
.read()
|
||||||
.lookup_instance_traits(name, &mut class_traits)?;
|
.lookup_instance_traits(name, &mut class_traits)?;
|
||||||
let base_trait = class_traits.first().ok_or_else(|| {
|
let base_trait = class_traits
|
||||||
format!(
|
.iter()
|
||||||
"Attempted to supercall method {:?}, which does not exist",
|
.find(|t| matches!(t.kind(), TraitKind::Setter { .. }))
|
||||||
name
|
.ok_or_else(|| {
|
||||||
)
|
format!(
|
||||||
})?;
|
"Attempted to supercall setter {:?}, which does not exist",
|
||||||
|
name
|
||||||
|
)
|
||||||
|
})?;
|
||||||
let scope = constr_with_trait.get_scope();
|
let scope = constr_with_trait.get_scope();
|
||||||
|
|
||||||
if let TraitKind::Setter { method, .. } = base_trait.kind() {
|
if let TraitKind::Setter { method, .. } = base_trait.kind() {
|
||||||
|
@ -872,11 +873,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(format!(
|
unreachable!();
|
||||||
"Attempted to supercall setter for {:?}, which does not exist",
|
|
||||||
name
|
|
||||||
)
|
|
||||||
.into())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue