avm2: Remove unnecessary range checks on local-modifying ops in optimizer

This commit is contained in:
Lord-McSweeney 2024-03-23 12:24:13 -07:00 committed by Lord-McSweeney
parent dec9f07f5f
commit 9f44281a52
1 changed files with 11 additions and 37 deletions

View File

@ -83,12 +83,8 @@ impl<'gc> Locals<'gc> {
self.0[index] = value; self.0[index] = value;
} }
fn at(&self, index: usize) -> Option<OptValue<'gc>> { fn at(&self, index: usize) -> OptValue<'gc> {
self.0.get(index).copied() self.0[index]
}
fn len(&self) -> usize {
self.0.len()
} }
} }
@ -242,21 +238,15 @@ pub fn optimize<'gc>(
| Op::IncLocalI { index } | Op::IncLocalI { index }
| Op::DecLocal { index } | Op::DecLocal { index }
| Op::DecLocalI { index } => { | Op::DecLocalI { index } => {
if (*index as usize) < initial_local_types.len() {
initial_local_types.set_any(*index as usize); initial_local_types.set_any(*index as usize);
} }
}
Op::HasNext2 { Op::HasNext2 {
object_register, object_register,
index_register, index_register,
} => { } => {
if (*object_register as usize) < initial_local_types.len() {
initial_local_types.set_any(*object_register as usize); initial_local_types.set_any(*object_register as usize);
}
if (*index_register as usize) < initial_local_types.len() {
initial_local_types.set_any(*index_register as usize); initial_local_types.set_any(*index_register as usize);
} }
}
_ => {} _ => {}
} }
} }
@ -384,15 +374,11 @@ pub fn optimize<'gc>(
stack.push_any(); stack.push_any();
} }
Op::DecLocalI { index } => { Op::DecLocalI { index } => {
if (*index as usize) < local_types.len() {
local_types.set_any(*index as usize); local_types.set_any(*index as usize);
} }
}
Op::IncLocalI { index } => { Op::IncLocalI { index } => {
if (*index as usize) < local_types.len() {
local_types.set_any(*index as usize); local_types.set_any(*index as usize);
} }
}
Op::Increment => { Op::Increment => {
stack.pop(); stack.pop();
stack.push_class_object(types.number); stack.push_class_object(types.number);
@ -605,27 +591,15 @@ pub fn optimize<'gc>(
} }
} }
Op::Kill { index } => { Op::Kill { index } => {
if (*index as usize) < local_types.len() {
local_types.set_any(*index as usize); local_types.set_any(*index as usize);
} }
}
Op::SetLocal { index } => { Op::SetLocal { index } => {
let stack_value = stack.pop(); let stack_value = stack.pop_or_any();
if (*index as usize) < local_types.len() {
if let Some(stack_value) = stack_value {
local_types.set(*index as usize, stack_value); local_types.set(*index as usize, stack_value);
} else {
local_types.set_any(*index as usize);
}
}
} }
Op::GetLocal { index } => { Op::GetLocal { index } => {
let local_type = local_types.at(*index as usize); let local_type = local_types.at(*index as usize);
if let Some(local_type) = local_type {
stack.push(local_type); stack.push(local_type);
} else {
stack.push_any();
}
} }
Op::GetLex { .. } => { Op::GetLex { .. } => {
stack.push_any(); stack.push_any();