avm1: Improve `StageObject::get_local_stored`

* Avoid an extraneous check to `ScriptObject::has_own_property`.
 * Avoid magic property branches if property name does not start
   with `_`.
This commit is contained in:
Mike Welsh 2022-05-08 12:06:44 -07:00
parent a940a0d357
commit 35d2f69396
1 changed files with 37 additions and 24 deletions

View File

@ -185,27 +185,38 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
let name = name.into(); let name = name.into();
let obj = self.0.read(); let obj = self.0.read();
let props = activation.context.avm1.display_properties; let props = activation.context.avm1.display_properties;
let case_sensitive = activation.is_case_sensitive();
// Property search order for DisplayObjects: // Property search order for DisplayObjects:
if self.has_own_property(activation, name) { // 1) Actual properties on the underlying object
// 1) Actual properties on the underlying object if let Some(value) = obj.base.get_local_stored(name, activation) {
obj.base.get_local_stored(name, activation) return Some(value);
} else if let Some(object) = self.resolve_path_property(name, activation) { }
// 2) Path properties such as `_root`, `_parent`, `_levelN` (obeys case sensitivity)
Some(object) // 2) Path properties such as `_root`, `_parent`, `_levelN` (obeys case sensitivity)
} else if let Some(child) = obj let magic_property = name.starts_with(b'_');
if magic_property {
if let Some(object) = self.resolve_path_property(name, activation) {
return Some(object);
}
}
// 3) Child display objects with the given instance name
if let Some(child) = obj
.display_object .display_object
.as_container() .as_container()
.and_then(|o| o.child_by_name(&name, case_sensitive)) .and_then(|o| o.child_by_name(&name, activation.is_case_sensitive()))
{ {
// 3) Child display objects with the given instance name return Some(child.object());
Some(child.object())
} else if let Some(property) = props.read().get_by_name(name) {
// 4) Display object properties such as `_x`, `_y` (never case sensitive)
Some(property.get(activation, obj.display_object))
} else {
None
} }
// 4) Display object properties such as `_x`, `_y` (never case sensitive)
if magic_property {
if let Some(property) = props.read().get_by_name(name) {
return Some(property.get(activation, obj.display_object));
}
}
None
} }
fn set_local( fn set_local(
@ -385,13 +396,15 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
return true; return true;
} }
if activation let magic_property = name.starts_with(b'_');
.context if magic_property
.avm1 && activation
.display_properties .context
.read() .avm1
.get_by_name(name) .display_properties
.is_some() .read()
.get_by_name(name)
.is_some()
{ {
return true; return true;
} }
@ -406,7 +419,7 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
return true; return true;
} }
if self.resolve_path_property(name, activation).is_some() { if magic_property && self.resolve_path_property(name, activation).is_some() {
return true; return true;
} }