Skip to content

Commit

Permalink
save more work
Browse files Browse the repository at this point in the history
  • Loading branch information
Lord-McSweeney authored and Lord-McSweeney committed Apr 2, 2024
1 parent 018faf7 commit da4a42d
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 2 deletions.
47 changes: 45 additions & 2 deletions core/src/avm2/activation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -888,8 +888,6 @@ impl<'a, 'gc> Activation<'a, 'gc> {
}

let op = &opcodes[self.ip as usize];
println!("|Op|?");
println!("|Op|{:?}", op);
self.ip += 1;
avm_debug!(self.avm2(), "Opcode: {op:?}");

Expand Down Expand Up @@ -1085,11 +1083,15 @@ impl<'a, 'gc> Activation<'a, 'gc> {
Op::ConstructLocal0Super => self.op_construct_local0_super(),
Op::DivideLocalLocal { index1, index2 } => self.op_divide_local_local(*index1, *index2),
Op::GetLocalSlot { index, slot_id } => self.op_get_local_slot(*index, *slot_id),
Op::IfLtLocalConstant { index, constant, offset } => self.op_if_lt_local_constant(*index, *constant, *offset),
Op::IfLtLocalLocal { index1, index2, offset } => self.op_if_lt_local_local(*index1, *index2, *offset),
Op::IfNeLocalConstant { index, constant, offset } => self.op_if_ne_local_constant(*index, *constant, *offset),
Op::IfNgtLocalConstant { index, constant, offset } => self.op_if_ngt_local_constant(*index, *constant, *offset),
Op::IncrementLocalCoerceU { index } => self.op_increment_local_coerce_u(*index),
Op::Li8Local { index } => self.op_li8_local(*index),
Op::MultiplyLocalLocal { index1, index2 } => self.op_multiply_local_local(*index1, *index2),
Op::PushScopeLocal0 => self.op_push_scope_local0(),
Op::SetLocalAddICoerceI { index } => self.op_set_local_add_i_coerce_i(*index),
Op::SetLocalConstant { index, constant } => self.op_set_local_constant(*index, *constant),
Op::SetLocalNaN { index } => self.op_set_local_nan(*index),
Op::SetLocalNull { index } => self.op_set_local_null(*index),
Expand Down Expand Up @@ -3333,6 +3335,16 @@ impl<'a, 'gc> Activation<'a, 'gc> {
Ok(FrameControl::Continue)
}

fn op_if_lt_local_constant(&mut self, index: u32, constant: i32, offset: i32) -> Result<FrameControl<'gc>, Error<'gc>> {
let value = self.local_register(index);

if value.abstract_lt(&Value::from(constant), self)? == Some(true) {
self.ip += offset;
}

Ok(FrameControl::Continue)
}

fn op_if_lt_local_local(&mut self, index1: u32, index2: u32, offset: i32) -> Result<FrameControl<'gc>, Error<'gc>> {
let value2 = self.local_register(index2);
let value1 = self.local_register(index1);
Expand All @@ -3354,6 +3366,25 @@ impl<'a, 'gc> Activation<'a, 'gc> {
Ok(FrameControl::Continue)
}

fn op_if_ngt_local_constant(&mut self, index: u32, constant: i32, offset: i32) -> Result<FrameControl<'gc>, Error<'gc>> {
let value = self.local_register(index);

if !Value::from(constant).abstract_lt(&value, self)?.unwrap_or(false) {
self.ip += offset;
}

Ok(FrameControl::Continue)
}

fn op_increment_local_coerce_u(&mut self, index: u32) -> Result<FrameControl<'gc>, Error<'gc>> {
let value = self.local_register(index).coerce_to_number(self)?;
let coerced_value = crate::ecma_conversions::f64_to_wrapping_u32(value + 1.0);

self.set_local_register(index, coerced_value);

Ok(FrameControl::Continue)
}

fn op_li8_local(&mut self, index: u32) -> Result<FrameControl<'gc>, Error<'gc>> {
let address = self.local_register(index).coerce_to_u32(self)? as usize;

Expand Down Expand Up @@ -3388,6 +3419,18 @@ impl<'a, 'gc> Activation<'a, 'gc> {
Ok(FrameControl::Continue)
}

fn op_set_local_add_i_coerce_i(&mut self, index: u32) -> Result<FrameControl<'gc>, Error<'gc>> {
let value2 = self.pop_stack().coerce_to_i32(self)?;
let value1 = self.pop_stack().coerce_to_i32(self)?;

// FIXME: Check if the value conversion and the `coerce_to_i32` are necessary
let value = Value::from(value1.wrapping_add(value2)).coerce_to_i32(self)?;

self.set_local_register(index, value);

Ok(FrameControl::Continue)
}

fn op_set_local_constant(&mut self, index: u32, constant: i32) -> Result<FrameControl<'gc>, Error<'gc>> {
self.set_local_register(index, constant);

Expand Down
18 changes: 18 additions & 0 deletions core/src/avm2/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,12 @@ pub enum Op<'gc> {
index: u32,
slot_id: u32,
},
IfLtLocalConstant {
index: u32,
constant: i32,

offset: i32,
},
IfLtLocalLocal {
index1: u32,
index2: u32,
Expand All @@ -380,6 +386,15 @@ pub enum Op<'gc> {

offset: i32,
},
IfNgtLocalConstant {
index: u32,
constant: i32,

offset: i32,
},
IncrementLocalCoerceU {
index: u32,
},
Li8Local {
index: u32,
},
Expand All @@ -388,6 +403,9 @@ pub enum Op<'gc> {
index2: u32,
},
PushScopeLocal0,
SetLocalAddICoerceI {
index: u32,
},
SetLocalConstant {
index: u32,
constant: i32,
Expand Down
52 changes: 52 additions & 0 deletions core/src/avm2/optimize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,19 @@ pub fn optimize<'gc>(
code[i] = Op::DivideLocalLocal { index1, index2 };
}

// IfLtLocalConstant
[_, Op::GetLocal { index }, Op::PushByte { value: constant }, Op::IfLt { offset }] => {
code[i - 2] = Op::Nop;
code[i - 1] = Op::Nop;
code[i] = Op::IfLtLocalConstant { index, constant: constant as i32, offset };
}
[Op::GetLocal { index }, Op::PushByte { value: constant }, Op::Nop, Op::IfLt { offset }] => {
code[i - 3] = Op::Nop;
code[i - 2] = Op::Nop;
code[i - 1] = Op::Nop;
code[i] = Op::IfLtLocalConstant { index, constant: constant as i32, offset };
}

// IfLtLocalLocal
[_, Op::GetLocal { index: index1 }, Op::GetLocal { index: index2 }, Op::IfLt { offset }] => {
code[i - 2] = Op::Nop;
Expand Down Expand Up @@ -1157,6 +1170,38 @@ pub fn optimize<'gc>(
code[i] = Op::IfNeLocalConstant { index, constant, offset };
}

// IfNgtLocalConstant
[_, Op::GetLocal { index }, Op::PushByte { value: constant }, Op::IfNgt { offset }] => {
code[i - 2] = Op::Nop;
code[i - 1] = Op::Nop;
code[i] = Op::IfNgtLocalConstant { index, constant: constant as i32, offset };
}
[_, Op::GetLocal { index }, Op::PushInt { value: constant }, Op::IfNgt { offset }] => {
code[i - 2] = Op::Nop;
code[i - 1] = Op::Nop;
code[i] = Op::IfNgtLocalConstant { index, constant, offset };
}
[Op::GetLocal { index }, Op::PushByte { value: constant }, Op::Nop, Op::IfNgt { offset }] => {
code[i - 3] = Op::Nop;
code[i - 2] = Op::Nop;
code[i - 1] = Op::Nop;
code[i] = Op::IfNgtLocalConstant { index, constant: constant as i32, offset };
}
[Op::GetLocal { index }, Op::PushInt { value: constant }, Op::Nop, Op::IfNgt { offset }] => {
code[i - 3] = Op::Nop;
code[i - 2] = Op::Nop;
code[i - 1] = Op::Nop;
code[i] = Op::IfNgtLocalConstant { index, constant, offset };
}

// IncrementLocalCoerceU
[Op::GetLocal { index: index1 }, Op::Increment, Op::CoerceU, Op::SetLocal { index: index2 }] if index1 == index2 => {
code[i - 3] = Op::Nop;
code[i - 2] = Op::Nop;
code[i - 1] = Op::Nop;
code[i] = Op::IncrementLocalCoerceU { index: index1 };
}

// GetLocalSlot
// Ensure that this doesn't interfere with other optimizations, such as AddLocal0SlotInt
[Op::GetLocal { index }, Op::GetSlot { index: slot_id }, _, _] => {
Expand All @@ -1183,6 +1228,13 @@ pub fn optimize<'gc>(
code[i] = Op::PushScopeLocal0;
}

// SetLocalAddICoerceI
[_, Op::AddI, Op::CoerceI, Op::SetLocal { index }] => {
code[i - 2] = Op::Nop;
code[i - 1] = Op::Nop;
code[i] = Op::SetLocalAddICoerceI { index };
}

// SetLocalConstant
[_, _, Op::PushByte { value: constant }, Op::SetLocal { index }] => {
code[i - 1] = Op::Nop;
Expand Down

0 comments on commit da4a42d

Please sign in to comment.