Skip to content

Commit 6c794c1

Browse files
Lord-McSweeneyLord-McSweeney
authored andcommitted
avm2: Move interface logic from ClassObject to Class
1 parent cbe8d2a commit 6c794c1

File tree

4 files changed

+10
-64
lines changed

4 files changed

+10
-64
lines changed

core/src/avm2/class.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,10 @@ pub struct ClassData<'gc> {
104104
/// superinterfaces, nor interfaces implemented by the superclass.
105105
direct_interfaces: Vec<Class<'gc>>,
106106

107-
/// The list of all interfaces implemented by this class.
107+
/// Interfaces implemented by this class, including interfaces
108+
/// from parent classes and superinterfaces (recursively).
109+
/// TODO - avoid cloning this when a subclass implements the
110+
/// same interface as its superclass.
108111
all_interfaces: Vec<Class<'gc>>,
109112

110113
/// The instance allocator for this class.
@@ -633,7 +636,7 @@ impl<'gc> Class<'gc> {
633636
.into());
634637
}
635638

636-
if dedup.insert(ClassHashWrapper(*interface)) {
639+
if dedup.insert(*interface) {
637640
queue.push(*interface);
638641
interfaces.push(*interface);
639642
}
@@ -1149,18 +1152,3 @@ impl<'gc> Class<'gc> {
11491152
self.0.read().attributes.contains(ClassAttributes::GENERIC)
11501153
}
11511154
}
1152-
1153-
pub struct ClassHashWrapper<'gc>(pub Class<'gc>);
1154-
1155-
impl<'gc> PartialEq for ClassHashWrapper<'gc> {
1156-
fn eq(&self, other: &Self) -> bool {
1157-
GcCell::ptr_eq(self.0 .0, other.0 .0)
1158-
}
1159-
}
1160-
impl<'gc> Eq for ClassHashWrapper<'gc> {}
1161-
1162-
impl<'gc> Hash for ClassHashWrapper<'gc> {
1163-
fn hash<H: Hasher>(&self, state: &mut H) {
1164-
self.0 .0.as_ptr().hash(state);
1165-
}
1166-
}

core/src/avm2/globals/avmplus.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ fn describe_internal_body<'gc>(
279279
};
280280

281281
if flags.contains(DescribeTypeFlags::INCLUDE_INTERFACES) && use_instance_traits {
282-
for interface in class_obj.interfaces() {
282+
for interface in &*class_obj.inner_class_definition().all_interfaces() {
283283
let interface_name = interface
284284
.name()
285285
.to_qualified_name(activation.context.gc_context);

core/src/avm2/object/class_object.rs

Lines changed: 3 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Class object impl
22
33
use crate::avm2::activation::Activation;
4-
use crate::avm2::class::{Allocator, AllocatorFn, Class, ClassHashWrapper};
4+
use crate::avm2::class::{Allocator, AllocatorFn, Class};
55
use crate::avm2::error::{argument_error, make_error_1127, reference_error, type_error};
66
use crate::avm2::function::exec;
77
use crate::avm2::method::Method;
@@ -20,7 +20,6 @@ use crate::string::AvmString;
2020
use fnv::FnvHashMap;
2121
use gc_arena::{Collect, GcCell, GcWeakCell, Mutation};
2222
use std::cell::{BorrowError, Ref, RefMut};
23-
use std::collections::HashSet;
2423
use std::fmt::Debug;
2524
use std::hash::{Hash, Hasher};
2625

@@ -82,12 +81,6 @@ pub struct ClassObjectData<'gc> {
8281
/// we get a param of `null`.
8382
applications: FnvHashMap<Option<Class<'gc>>, ClassObject<'gc>>,
8483

85-
/// Interfaces implemented by this class, including interfaces
86-
/// from parent classes and superinterfaces (recursively).
87-
/// TODO - avoid cloning this when a subclass implements the
88-
/// same interface as its superclass.
89-
interfaces: Vec<Class<'gc>>,
90-
9184
/// VTable used for instances of this class.
9285
instance_vtable: VTable<'gc>,
9386

@@ -205,7 +198,6 @@ impl<'gc> ClassObject<'gc> {
205198
native_constructor: class.native_instance_init(),
206199
call_handler: class.call_handler(),
207200
applications: Default::default(),
208-
interfaces: Vec::new(),
209201
instance_vtable: VTable::empty(activation.context.gc_context),
210202
class_vtable: VTable::empty(activation.context.gc_context),
211203
},
@@ -318,43 +310,13 @@ impl<'gc> ClassObject<'gc> {
318310
/// instance traits will be resolved to their corresponding methods at this
319311
/// time.
320312
pub fn link_interfaces(self, activation: &mut Activation<'_, 'gc>) -> Result<(), Error<'gc>> {
321-
let mut write = self.0.write(activation.context.gc_context);
322-
let class = write.class;
323-
324-
let mut interfaces = Vec::with_capacity(class.direct_interfaces().len());
325-
326-
let mut dedup = HashSet::new();
327-
let mut queue = vec![class];
328-
while let Some(cls) = queue.pop() {
329-
for interface in &*cls.direct_interfaces() {
330-
if !interface.is_interface() {
331-
return Err(format!(
332-
"Class {:?} is not an interface and cannot be implemented by classes",
333-
interface.name().local_name()
334-
)
335-
.into());
336-
}
337-
338-
if dedup.insert(ClassHashWrapper(*interface)) {
339-
queue.push(*interface);
340-
interfaces.push(*interface);
341-
}
342-
}
343-
344-
if let Some(super_class) = cls.super_class() {
345-
queue.push(super_class);
346-
}
347-
}
348-
write.interfaces = interfaces;
349-
drop(write);
350-
351-
let read = self.0.read();
313+
let class = self.inner_class_definition();
352314

353315
// FIXME - we should only be copying properties for newly-implemented
354316
// interfaces (i.e. those that were not already implemented by the superclass)
355317
// Otherwise, our behavior diverges from Flash Player in certain cases.
356318
// See the ignored test 'tests/tests/swfs/avm2/weird_superinterface_properties/'
357-
for interface in &read.interfaces {
319+
for interface in &*class.all_interfaces() {
358320
for interface_trait in &*interface.instance_traits() {
359321
if !interface_trait.name().namespace().is_public() {
360322
let public_name = QName::new(
@@ -760,10 +722,6 @@ impl<'gc> ClassObject<'gc> {
760722
self.0.read().prototype.unwrap()
761723
}
762724

763-
pub fn interfaces(self) -> Vec<Class<'gc>> {
764-
self.0.read().interfaces.clone()
765-
}
766-
767725
pub fn class_scope(self) -> ScopeChain<'gc> {
768726
self.0.read().class_scope
769727
}

core/src/debug_ui/avm2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ impl Avm2ObjectWindow {
213213

214214
ui.label("Interfaces");
215215
ui.vertical(|ui| {
216-
for interface in class.interfaces() {
216+
for interface in &*class.inner_class_definition().all_interfaces() {
217217
ui.text_edit_singleline(
218218
&mut interface
219219
.name()

0 commit comments

Comments
 (0)