Skip to content

Commit

Permalink
avm2: Merge locals better
Browse files Browse the repository at this point in the history
  • Loading branch information
Lord-McSweeney authored and torokati44 committed Jun 18, 2024
1 parent 8d77802 commit 5f90327
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 9 deletions.
39 changes: 30 additions & 9 deletions core/src/avm2/optimize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use gc_arena::Gc;
use std::collections::HashMap;

#[allow(clippy::enum_variant_names)]
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq)]
enum NullState {
NotNull,
MaybeNull,
Expand Down Expand Up @@ -101,6 +101,33 @@ impl<'gc> OptValue<'gc> {
|| self.class == Some(classes.boolean.inner_class_definition())
|| self.class == Some(classes.void.inner_class_definition())
}

pub fn merged_with(self, other: OptValue<'gc>) -> OptValue<'gc> {
let mut created_value = OptValue::any();

// TODO: Also check common superclasses.
if self.class == other.class {
created_value.class = self.class;
}

if self.vtable == other.vtable {
created_value.vtable = self.vtable;
}

if self.null_state == other.null_state {
created_value.null_state = self.null_state;
}

if self.contains_valid_integer && other.contains_valid_integer {
created_value.contains_valid_integer = true;
}

if self.contains_valid_unsigned && other.contains_valid_unsigned {
created_value.contains_valid_unsigned = true;
}

return created_value;
}
}

impl<'gc> std::fmt::Debug for OptValue<'gc> {
Expand Down Expand Up @@ -374,14 +401,8 @@ pub fn optimize<'gc>(
} else {
for (i, target_local) in local_types.0.iter().enumerate() {
let source_local = source_local_types.at(i);
// TODO: Check superclasses, too
if let (Some(source_local_class), Some(target_local_class)) =
(source_local.class, target_local.class)
{
if source_local_class == target_local_class {
merged_types.set(i, OptValue::of_type(source_local_class));
}
}

merged_types.set(i, source_local.merged_with(*target_local));
}
}

Expand Down
6 changes: 6 additions & 0 deletions core/src/avm2/vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ pub struct VTableData<'gc> {
default_slots: Vec<Option<Value<'gc>>>,
}

impl PartialEq for VTable<'_> {
fn eq(&self, other: &Self) -> bool {
GcCell::ptr_eq(self.0, other.0)
}
}

// TODO: it might make more sense to just bind the Method to the VTable (and this its class and scope) directly
// would also be nice to somehow remove the Option-ness from `defining_class` and `scope` fields for this
// to be more intuitive and cheaper
Expand Down

0 comments on commit 5f90327

Please sign in to comment.