Skip to content

Commit 5ff5bf0

Browse files
Lord-McSweeneyLord-McSweeney
authored andcommitted
avm2: Optimize ConstructProp to ConstructSlot when possible
1 parent 1eda9f4 commit 5ff5bf0

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

core/src/avm2/activation.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
883883
multiname,
884884
num_args,
885885
} => self.op_construct_prop(*multiname, *num_args),
886+
Op::ConstructSlot { index, num_args } => self.op_construct_slot(*index, *num_args),
886887
Op::ConstructSuper { num_args } => self.op_construct_super(*num_args),
887888
Op::NewActivation => self.op_new_activation(),
888889
Op::NewObject { num_args } => self.op_new_object(*num_args),
@@ -1729,6 +1730,26 @@ impl<'a, 'gc> Activation<'a, 'gc> {
17291730
Ok(FrameControl::Continue)
17301731
}
17311732

1733+
fn op_construct_slot(
1734+
&mut self,
1735+
index: u32,
1736+
arg_count: u32,
1737+
) -> Result<FrameControl<'gc>, Error<'gc>> {
1738+
let args = self.pop_stack_args(arg_count);
1739+
let source = self
1740+
.pop_stack()
1741+
.null_check(self, None)?
1742+
.as_object()
1743+
.expect("Cannot get_slot on primitive");
1744+
1745+
let ctor = source.get_slot(index);
1746+
let constructed_object = ctor.construct(self, &args)?;
1747+
1748+
self.push_stack(constructed_object);
1749+
1750+
Ok(FrameControl::Continue)
1751+
}
1752+
17321753
fn op_construct_super(&mut self, arg_count: u32) -> Result<FrameControl<'gc>, Error<'gc>> {
17331754
let args = self.pop_stack_args(arg_count);
17341755
let receiver = self.pop_stack().null_check(self, None)?;

core/src/avm2/op.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ pub enum Op<'gc> {
8484
multiname: Gc<'gc, Multiname<'gc>>,
8585
num_args: u32,
8686
},
87+
ConstructSlot {
88+
index: u32,
89+
num_args: u32,
90+
},
8791
ConstructSuper {
8892
num_args: u32,
8993
},

core/src/avm2/optimizer/optimize.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,6 +1532,11 @@ fn abstract_interpret_ops<'gc>(
15321532
match vtable.get_trait(&multiname) {
15331533
Some(Property::Slot { slot_id })
15341534
| Some(Property::ConstSlot { slot_id }) => {
1535+
optimize_op_to!(Op::ConstructSlot {
1536+
index: slot_id,
1537+
num_args
1538+
});
1539+
15351540
let mut value_class = vtable.slot_classes()[slot_id as usize];
15361541
let resolved_value_class = value_class.get_class(activation)?;
15371542

@@ -1798,6 +1803,7 @@ fn abstract_interpret_ops<'gc>(
17981803
| Op::CoerceDSwapPop
17991804
| Op::CoerceISwapPop
18001805
| Op::CoerceUSwapPop
1806+
| Op::ConstructSlot { .. }
18011807
| Op::GetScriptGlobals { .. }
18021808
| Op::SetSlotNoCoerce { .. } => unreachable!("Custom ops should not be encountered"),
18031809
}

0 commit comments

Comments
 (0)