diff --git a/core/src/avm2/class.rs b/core/src/avm2/class.rs
index 247f3a207..d25326da6 100644
--- a/core/src/avm2/class.rs
+++ b/core/src/avm2/class.rs
@@ -833,10 +833,11 @@ impl<'gc> Class<'gc> {
false
}
- /// Determines if this class provides a given trait on its instances.
- pub fn has_instance_trait_by_id(&self, id: u32) -> bool {
+ /// Determines if this class provides a given trait with a particular
+ /// dispatch ID on its instances.
+ pub fn has_instance_trait_by_disp_id(&self, id: u32) -> bool {
for trait_entry in self.instance_traits.iter() {
- if id == trait_entry.slot_id() {
+ if Some(id) == trait_entry.disp_id() {
return true;
}
}
diff --git a/core/src/avm2/object/class_object.rs b/core/src/avm2/object/class_object.rs
index 2a8d43eea..3ed1310ca 100644
--- a/core/src/avm2/object/class_object.rs
+++ b/core/src/avm2/object/class_object.rs
@@ -386,15 +386,18 @@ impl<'gc> ClassObject<'gc> {
///
/// This function returns `None` for non-trait properties, such as actually
/// defined prototype methods for ES3-style classes.
- pub fn find_class_for_trait_by_id(self, id: u32) -> Result>, Error> {
+ pub fn find_class_for_trait_by_disp_id(
+ self,
+ id: u32,
+ ) -> Result >, Error> {
let class_definition = self.inner_class_definition();
- if class_definition.read().has_instance_trait_by_id(id) {
+ if class_definition.read().has_instance_trait_by_disp_id(id) {
return Ok(Some(self));
}
if let Some(base) = self.superclass_object() {
- return base.find_class_for_trait_by_id(id);
+ return base.find_class_for_trait_by_disp_id(id);
}
Ok(None)
@@ -749,7 +752,7 @@ impl<'gc> ClassObject<'gc> {
) -> Result , u32)>, Error> {
if let Some((superclass, method_trait)) = self.instance_method(name)? {
let method = method_trait.as_method().unwrap();
- let disp_id = method_trait.slot_id();
+ let disp_id = method_trait.disp_id().unwrap();
let scope = self.instance_scope();
Ok(Some((
@@ -783,7 +786,7 @@ impl<'gc> ClassObject<'gc> {
receiver: Object<'gc>,
id: u32,
) -> Result , QName<'gc>)>, Error> {
- if let Some(superclass) = self.find_class_for_trait_by_id(id)? {
+ if let Some(superclass) = self.find_class_for_trait_by_disp_id(id)? {
let superclassdef = superclass.inner_class_definition();
let traits = superclassdef.read().lookup_instance_traits_by_slot(id)?;
@@ -847,7 +850,7 @@ impl<'gc> ClassObject<'gc> {
) -> Result , u32)>, Error> {
if let Some(method_trait) = self.class_method(name)? {
let method = method_trait.as_method().unwrap();
- let disp_id = method_trait.slot_id();
+ let disp_id = method_trait.disp_id().unwrap();
let scope = self.class_scope();
Ok(Some((
diff --git a/core/src/avm2/traits.rs b/core/src/avm2/traits.rs
index 15bc088fc..d9eac4cd4 100644
--- a/core/src/avm2/traits.rs
+++ b/core/src/avm2/traits.rs
@@ -300,32 +300,58 @@ impl<'gc> Trait<'gc> {
self
}
- /// Get the slot or dispatch ID of this trait.
- pub fn slot_id(&self) -> u32 {
+ /// Get the slot ID of this trait.
+ pub fn slot_id(&self) -> Option {
match self.kind {
- TraitKind::Slot { slot_id, .. } => slot_id,
- TraitKind::Method { disp_id, .. } => disp_id,
- TraitKind::Getter { disp_id, .. } => disp_id,
- TraitKind::Setter { disp_id, .. } => disp_id,
- TraitKind::Class { slot_id, .. } => slot_id,
- TraitKind::Function { slot_id, .. } => slot_id,
- TraitKind::Const { slot_id, .. } => slot_id,
+ TraitKind::Slot { slot_id, .. } => Some(slot_id),
+ TraitKind::Method { .. } => None,
+ TraitKind::Getter { .. } => None,
+ TraitKind::Setter { .. } => None,
+ TraitKind::Class { slot_id, .. } => Some(slot_id),
+ TraitKind::Function { slot_id, .. } => Some(slot_id),
+ TraitKind::Const { slot_id, .. } => Some(slot_id),
}
}
- /// Set the slot or dispatch ID of this trait.
+ /// Set the slot ID of this trait.
pub fn set_slot_id(&mut self, id: u32) {
match &mut self.kind {
TraitKind::Slot { slot_id, .. } => *slot_id = id,
- TraitKind::Method { disp_id, .. } => *disp_id = id,
- TraitKind::Getter { disp_id, .. } => *disp_id = id,
- TraitKind::Setter { disp_id, .. } => *disp_id = id,
+ TraitKind::Method { .. } => {}
+ TraitKind::Getter { .. } => {}
+ TraitKind::Setter { .. } => {}
TraitKind::Class { slot_id, .. } => *slot_id = id,
TraitKind::Function { slot_id, .. } => *slot_id = id,
TraitKind::Const { slot_id, .. } => *slot_id = id,
}
}
+ /// Get the dispatch ID of this trait.
+ pub fn disp_id(&self) -> Option {
+ match self.kind {
+ TraitKind::Slot { .. } => None,
+ TraitKind::Method { disp_id, .. } => Some(disp_id),
+ TraitKind::Getter { disp_id, .. } => Some(disp_id),
+ TraitKind::Setter { disp_id, .. } => Some(disp_id),
+ TraitKind::Class { .. } => None,
+ TraitKind::Function { .. } => None,
+ TraitKind::Const { .. } => None,
+ }
+ }
+
+ /// Set the dispatch ID of this trait.
+ pub fn set_disp_id(&mut self, id: u32) {
+ match &mut self.kind {
+ TraitKind::Slot { .. } => {}
+ TraitKind::Method { disp_id, .. } => *disp_id = id,
+ TraitKind::Getter { disp_id, .. } => *disp_id = id,
+ TraitKind::Setter { disp_id, .. } => *disp_id = id,
+ TraitKind::Class { .. } => {}
+ TraitKind::Function { .. } => {}
+ TraitKind::Const { .. } => {}
+ }
+ }
+
/// Get the method contained within this trait, if it has one.
pub fn as_method(&self) -> Option> {
match &self.kind {