avm2: `get_property` does not mutate the underlying object (anymore) so it should not be flagged as mutably borrowing it.

This commit is contained in:
David Wendt 2021-07-19 18:00:33 -04:00
parent c30014baed
commit db86ca84b9
19 changed files with 51 additions and 61 deletions

View File

@ -211,7 +211,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
let class = self
.scope()
.ok_or("Cannot resolve parameter types without a scope stack")?
.write(self.context.gc_context)
.read()
.resolve(&type_name, self)?
.ok_or_else(|| format!("Could not resolve parameter type {:?}", type_name))?
.coerce_to_object(self)?;
@ -1076,7 +1076,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
) -> Result<FrameControl<'gc>, Error> {
let args = self.context.avm2.pop_args(arg_count);
let multiname = self.pool_multiname(method, index)?;
let mut receiver = self.context.avm2.pop().coerce_to_object(self)?;
let receiver = self.context.avm2.pop().coerce_to_object(self)?;
let name: Result<QName, Error> = receiver
.resolve_multiname(&multiname)?
.ok_or_else(|| format!("Could not find method {:?}", multiname.local_name()).into());
@ -1104,7 +1104,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
) -> Result<FrameControl<'gc>, Error> {
let args = self.context.avm2.pop_args(arg_count);
let multiname = self.pool_multiname(method, index)?;
let mut receiver = self.context.avm2.pop().coerce_to_object(self)?;
let receiver = self.context.avm2.pop().coerce_to_object(self)?;
let name: Result<QName, Error> = receiver
.resolve_multiname(&multiname)?
.ok_or_else(|| format!("Could not find method {:?}", multiname.local_name()).into());
@ -1126,7 +1126,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
) -> Result<FrameControl<'gc>, Error> {
let args = self.context.avm2.pop_args(arg_count);
let multiname = self.pool_multiname(method, index)?;
let mut receiver = self.context.avm2.pop().coerce_to_object(self)?;
let receiver = self.context.avm2.pop().coerce_to_object(self)?;
let name: Result<QName, Error> = receiver
.resolve_multiname(&multiname)?
.ok_or_else(|| format!("Could not find method {:?}", multiname.local_name()).into());
@ -1241,7 +1241,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
index: Index<AbcMultiname>,
) -> Result<FrameControl<'gc>, Error> {
let multiname = self.pool_multiname(method, index)?;
let mut object = self.context.avm2.pop().coerce_to_object(self)?;
let object = self.context.avm2.pop().coerce_to_object(self)?;
let name: Result<QName, Error> = object.resolve_multiname(&multiname)?.ok_or_else(|| {
format!("Could not resolve property {:?}", multiname.local_name()).into()
@ -1512,9 +1512,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
let multiname = self.pool_multiname_static(method, index)?;
avm_debug!(self.avm2(), "Resolving {:?}", multiname);
let found: Result<Value<'gc>, Error> = if let Some(scope) = self.scope() {
scope
.write(self.context.gc_context)
.resolve(&multiname, self)?
scope.read().resolve(&multiname, self)?
} else {
None
}
@ -1583,7 +1581,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
) -> Result<FrameControl<'gc>, Error> {
let args = self.context.avm2.pop_args(arg_count);
let multiname = self.pool_multiname(method, index)?;
let mut source = self.context.avm2.pop().coerce_to_object(self)?;
let source = self.context.avm2.pop().coerce_to_object(self)?;
let ctor_name: Result<QName, Error> =
source.resolve_multiname(&multiname)?.ok_or_else(|| {
@ -2393,7 +2391,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
fn op_next_value(&mut self) -> Result<FrameControl<'gc>, Error> {
let cur_index = self.context.avm2.pop().coerce_to_number(self)?;
let mut object = self.context.avm2.pop().coerce_to_object(self)?;
let object = self.context.avm2.pop().coerce_to_object(self)?;
let name = object.get_enumerant_name(cur_index as u32);
let value = if let Some(name) = name {
@ -2416,9 +2414,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
let multiname = self.pool_multiname_static(method, type_name_index)?;
let found: Result<Value<'gc>, Error> = if let Some(scope) = self.scope() {
scope
.write(self.context.gc_context)
.resolve(&multiname, self)?
scope.read().resolve(&multiname, self)?
} else {
None
}
@ -2457,9 +2453,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
let multiname = self.pool_multiname_static(method, type_name_index)?;
let found: Result<Value<'gc>, Error> = if let Some(scope) = self.scope() {
scope
.write(self.context.gc_context)
.resolve(&multiname, self)?
scope.read().resolve(&multiname, self)?
} else {
None
}

View File

@ -143,7 +143,7 @@ impl<'gc> Domain<'gc> {
let (name, mut script) = self
.get_defining_script(&name.clone().into())?
.ok_or_else(|| format!("MovieClip Symbol {} does not exist", name.local_name()))?;
let mut globals = script.globals(&mut activation.context)?;
let globals = script.globals(&mut activation.context)?;
globals.get_property(globals, &name, activation)
}

View File

@ -362,7 +362,7 @@ pub fn parent_of(target: Object<'_>) -> Option<Object<'_>> {
/// call the wrong handlers.
pub fn dispatch_event_to_target<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
mut target: Object<'gc>,
target: Object<'gc>,
event: Object<'gc>,
) -> Result<(), Error> {
avm_debug!(
@ -422,7 +422,7 @@ pub fn dispatch_event_to_target<'gc>(
pub fn dispatch_event<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
mut this: Object<'gc>,
this: Object<'gc>,
event: Object<'gc>,
) -> Result<bool, Error> {
let target = this

View File

@ -330,7 +330,7 @@ fn class<'gc>(
let class_name = class_read.name().clone();
drop(class_read);
let mut class_object =
let class_object =
ClassObject::from_class(activation, class_def, super_class, Some(global_scope))?;
global.install_const(
activation.context.gc_context,

View File

@ -130,7 +130,7 @@ pub fn resolve_array_hole<'gc>(
) -> Result<Value<'gc>, Error> {
item.map(Ok).unwrap_or_else(|| {
this.proto()
.map(|mut p| {
.map(|p| {
p.get_property(
p,
&QName::new(
@ -213,7 +213,7 @@ pub fn to_locale_string<'gc>(
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
join_inner(act, this, &[",".into()], |v, activation| {
let mut o = v.coerce_to_object(activation)?;
let o = v.coerce_to_object(activation)?;
let tls = o.get_property(
o,
@ -263,7 +263,7 @@ impl<'gc> ArrayIter<'gc> {
/// Construct a new `ArrayIter`.
pub fn new(
activation: &mut Activation<'_, 'gc, '_>,
mut array_object: Object<'gc>,
array_object: Object<'gc>,
) -> Result<Self, Error> {
let length = array_object
.get_property(
@ -1159,14 +1159,14 @@ pub fn sort_on<'gc>(
first_option,
constrain(|activation, a, b| {
for (field_name, options) in field_names.iter().zip(options.iter()) {
let mut a_object = a.coerce_to_object(activation)?;
let a_object = a.coerce_to_object(activation)?;
let a_field = a_object.get_property(
a_object,
&QName::new(Namespace::public(), *field_name),
activation,
)?;
let mut b_object = b.coerce_to_object(activation)?;
let b_object = b.coerce_to_object(activation)?;
let b_field = b_object.get_property(
b_object,
&QName::new(Namespace::public(), *field_name),

View File

@ -61,7 +61,7 @@ pub fn name<'gc>(
this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
if let Some(mut this) = this {
if let Some(this) = this {
return this.get_property(
this,
&QName::new(Namespace::Private("ruffle".into()), "name"),
@ -78,7 +78,7 @@ pub fn frame<'gc>(
this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
if let Some(mut this) = this {
if let Some(this) = this {
return this.get_property(
this,
&QName::new(Namespace::Private("ruffle".into()), "frame"),

View File

@ -68,7 +68,7 @@ pub fn labels<'gc>(
this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
if let Some(mut this) = this {
if let Some(this) = this {
this.get_property(
this,
&QName::new(Namespace::Private("ruffle".into()), "labels"),
@ -85,7 +85,7 @@ pub fn name<'gc>(
this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
if let Some(mut this) = this {
if let Some(this) = this {
this.get_property(
this,
&QName::new(Namespace::Private("ruffle".into()), "name"),
@ -102,7 +102,7 @@ pub fn num_frames<'gc>(
this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
if let Some(mut this) = this {
if let Some(this) = this {
this.get_property(
this,
&QName::new(Namespace::Private("ruffle".into()), "numFrames"),

View File

@ -158,7 +158,7 @@ pub fn format_to_string<'gc>(
) -> Result<Value<'gc>, Error> {
use std::fmt::Write;
if let Some(mut this) = this {
if let Some(this) = this {
let class_name = args
.get(0)
.cloned()

View File

@ -49,7 +49,7 @@ pub fn add_event_listener<'gc>(
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
if let Some(mut this) = this {
if let Some(this) = this {
let dispatch_list = this
.get_property(
this,
@ -96,7 +96,7 @@ pub fn remove_event_listener<'gc>(
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
if let Some(mut this) = this {
if let Some(this) = this {
let dispatch_list = this
.get_property(
this,
@ -135,7 +135,7 @@ pub fn has_event_listener<'gc>(
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
if let Some(mut this) = this {
if let Some(this) = this {
let dispatch_list = this
.get_property(
this,
@ -165,7 +165,7 @@ pub fn will_trigger<'gc>(
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
if let Some(mut this) = this {
if let Some(this) = this {
let dispatch_list = this
.get_property(
this,

View File

@ -79,7 +79,7 @@ pub fn get_definition<'gc>(
let (qname, mut defined_script) = appdomain
.get_defining_script(&qname.into())?
.ok_or_else(|| format!("No definition called {} exists", local_name))?;
let mut globals = defined_script.globals(&mut activation.context)?;
let globals = defined_script.globals(&mut activation.context)?;
let definition = globals.get_property(globals, &qname, activation)?;
return Ok(definition);

View File

@ -89,7 +89,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
/// Retrieve a property by its QName.
fn get_property(
&mut self,
self,
receiver: Object<'gc>,
name: &QName<'gc>,
activation: &mut Activation<'_, 'gc, '_>,
@ -100,7 +100,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
return self.get_property_local(receiver, name, activation);
}
if let Some(mut proto) = self.proto() {
if let Some(proto) = self.proto() {
return proto.get_property(receiver, name, activation);
}
@ -695,7 +695,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
callee.call(reciever, arguments, activation, Some(superclass_object))
} else {
if let Some(mut reciever) = reciever {
if let Some(reciever) = reciever {
if let Ok(callee) = reciever
.get_property(reciever, name, activation)
.and_then(|v| v.coerce_to_object(activation))
@ -760,7 +760,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
let callee = FunctionObject::from_method(activation, method.clone(), scope, reciever);
callee.call(reciever, &[], activation, Some(superclass_object))
} else if let Some(mut reciever) = reciever {
} else if let Some(reciever) = reciever {
reciever.get_property(reciever, name, activation)
} else {
Err(format!(

View File

@ -90,7 +90,7 @@ impl<'gc> ClassObject<'gc> {
//TODO: Class prototypes are *not* instances of their class and should
//not be allocated by the class allocator, but instead should be
//regular objects
let mut class_proto = if let Some(mut superclass_object) = superclass_object {
let mut class_proto = if let Some(superclass_object) = superclass_object {
let base_proto = superclass_object
.get_property(
superclass_object,
@ -152,9 +152,7 @@ impl<'gc> ClassObject<'gc> {
let mut interfaces = Vec::with_capacity(interface_names.len());
for interface_name in interface_names {
let interface = if let Some(scope) = scope {
scope
.write(activation.context.gc_context)
.resolve(&interface_name, activation)?
scope.read().resolve(&interface_name, activation)?
} else {
None
};
@ -349,7 +347,7 @@ impl<'gc> TObject<'gc> for ClassObject<'gc> {
}
fn construct(
mut self,
self,
activation: &mut Activation<'_, 'gc, '_>,
arguments: &[Value<'gc>],
) -> Result<Object<'gc>, Error> {

View File

@ -130,7 +130,7 @@ impl<'gc> TObject<'gc> for DomainObject<'gc> {
}
fn derive(&self, activation: &mut Activation<'_, 'gc, '_>) -> Result<Object<'gc>, Error> {
let mut this: Object<'gc> = Object::DomainObject(*self);
let this: Object<'gc> = Object::DomainObject(*self);
let constr = this
.get_property(
this,

View File

@ -55,7 +55,7 @@ impl<'gc> EventObject<'gc> {
/// we will pull the `prototype` off the `class` given to us.
pub fn from_event(
activation: &mut Activation<'_, 'gc, '_>,
mut class: Object<'gc>,
class: Object<'gc>,
event: Event<'gc>,
) -> Result<Object<'gc>, Error> {
let proto = class

View File

@ -155,7 +155,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
}
fn construct(
mut self,
self,
activation: &mut Activation<'_, 'gc, '_>,
arguments: &[Value<'gc>],
) -> Result<Object<'gc>, Error> {

View File

@ -59,7 +59,7 @@ impl<'gc> StageObject<'gc> {
pub fn for_display_object(
activation: &mut Activation<'_, 'gc, '_>,
display_object: DisplayObject<'gc>,
mut class: Object<'gc>,
class: Object<'gc>,
) -> Result<Self, Error> {
let proto = class
.get_property(

View File

@ -138,7 +138,7 @@ impl<'gc> Scope<'gc> {
/// This function yields `None` if no such scope exists to provide the
/// property's value.
pub fn resolve(
&mut self,
&self,
name: &Multiname<'gc>,
activation: &mut Activation<'_, 'gc, '_>,
) -> Result<Option<Value<'gc>>, Error> {
@ -153,16 +153,14 @@ impl<'gc> Scope<'gc> {
}
if let Some(parent) = self.parent {
return parent
.write(activation.context.gc_context)
.resolve(name, activation);
return parent.read().resolve(name, activation);
}
if let Some(domain) = self.locals().as_application_domain() {
let script = domain.get_defining_script(name)?;
if let Some((qname, mut script)) = script {
let mut script_scope = script.globals(&mut activation.context)?;
let script_scope = script.globals(&mut activation.context)?;
return Ok(Some(script_scope.get_property(
script_scope,

View File

@ -300,7 +300,7 @@ impl<'gc> Value<'gc> {
match self {
Value::Object(o) if hint == Hint::String => {
let mut prim = self.clone();
let mut object = *o;
let object = *o;
if let Value::Object(f) =
object.get_property(*o, &QName::dynamic_name("toString"), activation)?
@ -326,7 +326,7 @@ impl<'gc> Value<'gc> {
}
Value::Object(o) if hint == Hint::Number => {
let mut prim = self.clone();
let mut object = *o;
let object = *o;
if let Value::Object(f) =
object.get_property(*o, &QName::dynamic_name("valueOf"), activation)?

View File

@ -190,7 +190,7 @@ fn getfloatarray_from_avm1_object<'gc>(
}
fn getstr_from_avm2_object<'gc>(
mut object: Avm2Object<'gc>,
object: Avm2Object<'gc>,
pubname: &'static str,
activation: &mut Avm2Activation<'_, 'gc, '_>,
) -> Result<Option<String>, Avm2Error> {
@ -208,7 +208,7 @@ fn getstr_from_avm2_object<'gc>(
}
fn getfloat_from_avm2_object<'gc>(
mut object: Avm2Object<'gc>,
object: Avm2Object<'gc>,
pubname: &'static str,
activation: &mut Avm2Activation<'_, 'gc, '_>,
) -> Result<Option<f64>, Avm2Error> {
@ -226,7 +226,7 @@ fn getfloat_from_avm2_object<'gc>(
}
fn getbool_from_avm2_object<'gc>(
mut object: Avm2Object<'gc>,
object: Avm2Object<'gc>,
pubname: &'static str,
activation: &mut Avm2Activation<'_, 'gc, '_>,
) -> Result<Option<bool>, Avm2Error> {
@ -244,7 +244,7 @@ fn getbool_from_avm2_object<'gc>(
}
fn getfloatarray_from_avm2_object<'gc>(
mut object: Avm2Object<'gc>,
object: Avm2Object<'gc>,
pubname: &'static str,
activation: &mut Avm2Activation<'_, 'gc, '_>,
) -> Result<Option<Vec<f64>>, Avm2Error> {
@ -257,7 +257,7 @@ fn getfloatarray_from_avm2_object<'gc>(
Avm2Value::Undefined => None,
Avm2Value::Null => None,
v => {
let mut v = v.coerce_to_object(activation)?;
let v = v.coerce_to_object(activation)?;
let length = v.as_array_storage().map(|v| v.length());
let mut output = Vec::new();