diff --git a/core/src/avm1/color_transform_object.rs b/core/src/avm1/color_transform_object.rs index 790991274..a38433d60 100644 --- a/core/src/avm1/color_transform_object.rs +++ b/core/src/avm1/color_transform_object.rs @@ -231,17 +231,23 @@ impl<'gc> TObject<'gc> for ColorTransformObject<'gc> { fn set_watcher( &self, + activation: &mut Activation<'_, 'gc>, gc_context: MutationContext<'gc, '_>, name: Cow, callback: Executable<'gc>, user_data: Value<'gc>, ) { self.base() - .set_watcher(gc_context, name, callback, user_data); + .set_watcher(activation, gc_context, name, callback, user_data); } - fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow) -> bool { - self.base().remove_watcher(gc_context, name) + fn remove_watcher( + &self, + activation: &mut Activation<'_, 'gc>, + gc_context: MutationContext<'gc, '_>, + name: Cow, + ) -> bool { + self.base().remove_watcher(activation, gc_context, name) } fn has_property( diff --git a/core/src/avm1/function.rs b/core/src/avm1/function.rs index 03f8324f5..36375132e 100644 --- a/core/src/avm1/function.rs +++ b/core/src/avm1/function.rs @@ -626,16 +626,23 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> { fn set_watcher( &self, + activation: &mut Activation<'_, 'gc>, gc_context: MutationContext<'gc, '_>, name: Cow, callback: Executable<'gc>, user_data: Value<'gc>, ) { - self.base.set_watcher(gc_context, name, callback, user_data); + self.base + .set_watcher(activation, gc_context, name, callback, user_data); } - fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow) -> bool { - self.base.remove_watcher(gc_context, name) + fn remove_watcher( + &self, + activation: &mut Activation<'_, 'gc>, + gc_context: MutationContext<'gc, '_>, + name: Cow, + ) -> bool { + self.base.remove_watcher(activation, gc_context, name) } fn has_property( diff --git a/core/src/avm1/globals/object.rs b/core/src/avm1/globals/object.rs index f0611552c..2fa618c1c 100644 --- a/core/src/avm1/globals/object.rs +++ b/core/src/avm1/globals/object.rs @@ -188,7 +188,7 @@ fn watch<'gc>( }; let user_data = args.get(2).cloned().unwrap_or(Value::Undefined); - this.set_watcher(context.gc_context, name, callback, user_data); + this.set_watcher(activation, context.gc_context, name, callback, user_data); Ok(true.into()) } @@ -206,7 +206,7 @@ fn unwatch<'gc>( return Ok(false.into()); }; - let result = this.remove_watcher(context.gc_context, name); + let result = this.remove_watcher(activation, context.gc_context, name); Ok(result.into()) } diff --git a/core/src/avm1/object.rs b/core/src/avm1/object.rs index 22d1784e9..6c40de327 100644 --- a/core/src/avm1/object.rs +++ b/core/src/avm1/object.rs @@ -264,6 +264,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy /// The property does not need to exist at the time of this being called. fn set_watcher( &self, + activation: &mut Activation<'_, 'gc>, gc_context: MutationContext<'gc, '_>, name: Cow, callback: Executable<'gc>, @@ -274,7 +275,12 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy /// /// The return value will indicate if there was a watcher present before this method was /// called. - fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow) -> bool; + fn remove_watcher( + &self, + activation: &mut Activation<'_, 'gc>, + gc_context: MutationContext<'gc, '_>, + name: Cow, + ) -> bool; /// Checks if the object has a given named property. fn has_property( diff --git a/core/src/avm1/script_object.rs b/core/src/avm1/script_object.rs index bbdc2400b..241a14e37 100644 --- a/core/src/avm1/script_object.rs +++ b/core/src/avm1/script_object.rs @@ -8,7 +8,6 @@ use core::fmt; use enumset::EnumSet; use gc_arena::{Collect, GcCell, MutationContext}; use std::borrow::Cow; -use std::collections::HashMap; pub const TYPE_OF_OBJECT: &str = "object"; @@ -73,7 +72,7 @@ pub struct ScriptObjectData<'gc> { interfaces: Vec>, type_of: &'static str, array: ArrayStorage<'gc>, - watchers: HashMap>, + watchers: PropertyMap>, } unsafe impl<'gc> Collect for ScriptObjectData<'gc> { @@ -110,7 +109,7 @@ impl<'gc> ScriptObject<'gc> { values: PropertyMap::new(), array: ArrayStorage::Properties { length: 0 }, interfaces: vec![], - watchers: HashMap::new(), + watchers: PropertyMap::new(), }, )) } @@ -127,7 +126,7 @@ impl<'gc> ScriptObject<'gc> { values: PropertyMap::new(), array: ArrayStorage::Vector(Vec::new()), interfaces: vec![], - watchers: HashMap::new(), + watchers: PropertyMap::new(), }, )); object.sync_native_property("length", gc_context, Some(0.into()), false); @@ -147,7 +146,7 @@ impl<'gc> ScriptObject<'gc> { values: PropertyMap::new(), array: ArrayStorage::Properties { length: 0 }, interfaces: vec![], - watchers: HashMap::new(), + watchers: PropertyMap::new(), }, )) .into() @@ -167,7 +166,7 @@ impl<'gc> ScriptObject<'gc> { values: PropertyMap::new(), array: ArrayStorage::Properties { length: 0 }, interfaces: vec![], - watchers: HashMap::new(), + watchers: PropertyMap::new(), }, )) } @@ -309,7 +308,12 @@ impl<'gc> ScriptObject<'gc> { //we'd resolve and return up there, but we have borrows that need //to end before we can do so. if !worked { - let watcher = self.0.read().watchers.get(name).cloned(); + let watcher = self + .0 + .read() + .watchers + .get(name, activation.is_case_sensitive()) + .cloned(); let mut return_value = Ok(()); if let Some(watcher) = watcher { let old_value = self.get(name, activation, context)?; @@ -557,19 +561,30 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> { fn set_watcher( &self, + activation: &mut Activation<'_, 'gc>, gc_context: MutationContext<'gc, '_>, name: Cow, callback: Executable<'gc>, user_data: Value<'gc>, ) { - self.0 - .write(gc_context) - .watchers - .insert(name.to_string(), Watcher::new(callback, user_data)); + self.0.write(gc_context).watchers.insert( + &name, + Watcher::new(callback, user_data), + activation.is_case_sensitive(), + ); } - fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow) -> bool { - let old = self.0.write(gc_context).watchers.remove(name.as_ref()); + fn remove_watcher( + &self, + activation: &mut Activation<'_, 'gc>, + gc_context: MutationContext<'gc, '_>, + name: Cow, + ) -> bool { + let old = self + .0 + .write(gc_context) + .watchers + .remove(name.as_ref(), activation.is_case_sensitive()); old.is_some() } diff --git a/core/src/avm1/shared_object.rs b/core/src/avm1/shared_object.rs index 92b5f5e1a..f64c91676 100644 --- a/core/src/avm1/shared_object.rs +++ b/core/src/avm1/shared_object.rs @@ -193,17 +193,23 @@ impl<'gc> TObject<'gc> for SharedObject<'gc> { fn set_watcher( &self, + activation: &mut Activation<'_, 'gc>, gc_context: MutationContext<'gc, '_>, name: Cow, callback: Executable<'gc>, user_data: Value<'gc>, ) { self.base() - .set_watcher(gc_context, name, callback, user_data); + .set_watcher(activation, gc_context, name, callback, user_data); } - fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow) -> bool { - self.base().remove_watcher(gc_context, name) + fn remove_watcher( + &self, + activation: &mut Activation<'_, 'gc>, + gc_context: MutationContext<'gc, '_>, + name: Cow, + ) -> bool { + self.base().remove_watcher(activation, gc_context, name) } fn has_property( diff --git a/core/src/avm1/sound_object.rs b/core/src/avm1/sound_object.rs index fa8627e39..b38fb8b83 100644 --- a/core/src/avm1/sound_object.rs +++ b/core/src/avm1/sound_object.rs @@ -253,17 +253,23 @@ impl<'gc> TObject<'gc> for SoundObject<'gc> { fn set_watcher( &self, + activation: &mut Activation<'_, 'gc>, gc_context: MutationContext<'gc, '_>, name: Cow, callback: Executable<'gc>, user_data: Value<'gc>, ) { self.base() - .set_watcher(gc_context, name, callback, user_data); + .set_watcher(activation, gc_context, name, callback, user_data); } - fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow) -> bool { - self.base().remove_watcher(gc_context, name) + fn remove_watcher( + &self, + activation: &mut Activation<'_, 'gc>, + gc_context: MutationContext<'gc, '_>, + name: Cow, + ) -> bool { + self.base().remove_watcher(activation, gc_context, name) } fn has_property( diff --git a/core/src/avm1/stage_object.rs b/core/src/avm1/stage_object.rs index fd0282f69..6d2b14e55 100644 --- a/core/src/avm1/stage_object.rs +++ b/core/src/avm1/stage_object.rs @@ -334,6 +334,7 @@ impl<'gc> TObject<'gc> for StageObject<'gc> { fn set_watcher( &self, + activation: &mut Activation<'_, 'gc>, gc_context: MutationContext<'gc, '_>, name: Cow, callback: Executable<'gc>, @@ -342,11 +343,19 @@ impl<'gc> TObject<'gc> for StageObject<'gc> { self.0 .read() .base - .set_watcher(gc_context, name, callback, user_data); + .set_watcher(activation, gc_context, name, callback, user_data); } - fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow) -> bool { - self.0.read().base.remove_watcher(gc_context, name) + fn remove_watcher( + &self, + activation: &mut Activation<'_, 'gc>, + gc_context: MutationContext<'gc, '_>, + name: Cow, + ) -> bool { + self.0 + .read() + .base + .remove_watcher(activation, gc_context, name) } fn has_property( diff --git a/core/src/avm1/super_object.rs b/core/src/avm1/super_object.rs index 156fe6022..6a717de1b 100644 --- a/core/src/avm1/super_object.rs +++ b/core/src/avm1/super_object.rs @@ -239,6 +239,7 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> { fn set_watcher( &self, + _activation: &mut Activation<'_, 'gc>, _gc_context: MutationContext<'gc, '_>, _name: Cow, _callback: Executable<'gc>, @@ -247,7 +248,12 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> { //`super` cannot have properties defined on it } - fn remove_watcher(&self, _gc_context: MutationContext<'gc, '_>, _name: Cow) -> bool { + fn remove_watcher( + &self, + _activation: &mut Activation<'_, 'gc>, + _gc_context: MutationContext<'gc, '_>, + _name: Cow, + ) -> bool { //`super` cannot have properties defined on it false } diff --git a/core/src/avm1/value_object.rs b/core/src/avm1/value_object.rs index a6ddacad8..3434c5b6c 100644 --- a/core/src/avm1/value_object.rs +++ b/core/src/avm1/value_object.rs @@ -233,6 +233,7 @@ impl<'gc> TObject<'gc> for ValueObject<'gc> { fn set_watcher( &self, + activation: &mut Activation<'_, 'gc>, gc_context: MutationContext<'gc, '_>, name: Cow, callback: Executable<'gc>, @@ -241,14 +242,19 @@ impl<'gc> TObject<'gc> for ValueObject<'gc> { self.0 .read() .base - .set_watcher(gc_context, name, callback, user_data); + .set_watcher(activation, gc_context, name, callback, user_data); } - fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow) -> bool { + fn remove_watcher( + &self, + activation: &mut Activation<'_, 'gc>, + gc_context: MutationContext<'gc, '_>, + name: Cow, + ) -> bool { self.0 .write(gc_context) .base - .remove_watcher(gc_context, name) + .remove_watcher(activation, gc_context, name) } fn define_value( diff --git a/core/src/avm1/xml_attributes_object.rs b/core/src/avm1/xml_attributes_object.rs index fe06c8998..67c374cc6 100644 --- a/core/src/avm1/xml_attributes_object.rs +++ b/core/src/avm1/xml_attributes_object.rs @@ -159,17 +159,23 @@ impl<'gc> TObject<'gc> for XMLAttributesObject<'gc> { fn set_watcher( &self, + activation: &mut Activation<'_, 'gc>, gc_context: MutationContext<'gc, '_>, name: Cow, callback: Executable<'gc>, user_data: Value<'gc>, ) { self.base() - .set_watcher(gc_context, name, callback, user_data); + .set_watcher(activation, gc_context, name, callback, user_data); } - fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow) -> bool { - self.base().remove_watcher(gc_context, name) + fn remove_watcher( + &self, + activation: &mut Activation<'_, 'gc>, + gc_context: MutationContext<'gc, '_>, + name: Cow, + ) -> bool { + self.base().remove_watcher(activation, gc_context, name) } fn define_value( diff --git a/core/src/avm1/xml_idmap_object.rs b/core/src/avm1/xml_idmap_object.rs index b53eeeae9..d0394b135 100644 --- a/core/src/avm1/xml_idmap_object.rs +++ b/core/src/avm1/xml_idmap_object.rs @@ -157,17 +157,23 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> { fn set_watcher( &self, + activation: &mut Activation<'_, 'gc>, gc_context: MutationContext<'gc, '_>, name: Cow, callback: Executable<'gc>, user_data: Value<'gc>, ) { self.base() - .set_watcher(gc_context, name, callback, user_data); + .set_watcher(activation, gc_context, name, callback, user_data); } - fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow) -> bool { - self.base().remove_watcher(gc_context, name) + fn remove_watcher( + &self, + activation: &mut Activation<'_, 'gc>, + gc_context: MutationContext<'gc, '_>, + name: Cow, + ) -> bool { + self.base().remove_watcher(activation, gc_context, name) } fn define_value( diff --git a/core/src/avm1/xml_object.rs b/core/src/avm1/xml_object.rs index 737d55702..1e548ed4a 100644 --- a/core/src/avm1/xml_object.rs +++ b/core/src/avm1/xml_object.rs @@ -147,17 +147,23 @@ impl<'gc> TObject<'gc> for XMLObject<'gc> { fn set_watcher( &self, + activation: &mut Activation<'_, 'gc>, gc_context: MutationContext<'gc, '_>, name: Cow, callback: Executable<'gc>, user_data: Value<'gc>, ) { self.base() - .set_watcher(gc_context, name, callback, user_data); + .set_watcher(activation, gc_context, name, callback, user_data); } - fn remove_watcher(&self, gc_context: MutationContext<'gc, '_>, name: Cow) -> bool { - self.base().remove_watcher(gc_context, name) + fn remove_watcher( + &self, + activation: &mut Activation<'_, 'gc>, + gc_context: MutationContext<'gc, '_>, + name: Cow, + ) -> bool { + self.base().remove_watcher(activation, gc_context, name) } fn define_value(