avm1: Make property watchers take Object, not Executable, so we can track the callee

This commit is contained in:
Nathan Adams 2020-07-22 22:43:55 +02:00 committed by Mike Welsh
parent 9ae10b6387
commit f4ab57d6e0
9 changed files with 29 additions and 30 deletions

View File

@ -619,7 +619,7 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> {
activation: &mut Activation<'_, 'gc>,
gc_context: MutationContext<'gc, '_>,
name: Cow<str>,
callback: Executable<'gc>,
callback: Object<'gc>,
user_data: Value<'gc>,
) {
self.base

View File

@ -174,18 +174,13 @@ fn watch<'gc>(
} else {
return Ok(false.into());
};
let callback = if let Some(callback) = args.get(1) {
if let Some(callback) = callback
.coerce_to_object(activation, context)
.as_executable()
{
callback
} else {
let callback = args
.get(1)
.unwrap_or(&Value::Undefined)
.coerce_to_object(activation, context);
if callback.as_executable().is_none() {
return Ok(false.into());
}
} else {
return Ok(false.into());
};
let user_data = args.get(2).cloned().unwrap_or(Value::Undefined);
this.set_watcher(

View File

@ -279,7 +279,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
activation: &mut Activation<'_, 'gc>,
gc_context: MutationContext<'gc, '_>,
name: Cow<str>,
callback: Executable<'gc>,
callback: Object<'gc>,
user_data: Value<'gc>,
);

View File

@ -240,7 +240,7 @@ macro_rules! impl_custom_object_without_set {
activation: &mut crate::avm1::Activation<'_, 'gc>,
gc_context: gc_arena::MutationContext<'gc, '_>,
name: std::borrow::Cow<str>,
callback: crate::avm1::function::Executable<'gc>,
callback: crate::avm1::object::Object<'gc>,
user_data: crate::avm1::Value<'gc>,
) {
self.0

View File

@ -21,12 +21,12 @@ pub enum ArrayStorage<'gc> {
#[derive(Debug, Clone, Collect)]
#[collect(no_drop)]
pub struct Watcher<'gc> {
callback: Executable<'gc>,
callback: Object<'gc>,
user_data: Value<'gc>,
}
impl<'gc> Watcher<'gc> {
pub fn new(callback: Executable<'gc>, user_data: Value<'gc>) -> Self {
pub fn new(callback: Object<'gc>, user_data: Value<'gc>) -> Self {
Self {
callback,
user_data,
@ -50,7 +50,8 @@ impl<'gc> Watcher<'gc> {
new_value,
self.user_data.clone(),
];
self.callback.exec(
if let Some(executable) = self.callback.as_executable() {
executable.exec(
name,
activation,
context,
@ -59,6 +60,9 @@ impl<'gc> Watcher<'gc> {
&args,
ExecutionReason::Special,
)
} else {
Ok(Value::Undefined)
}
}
}
@ -564,7 +568,7 @@ impl<'gc> TObject<'gc> for ScriptObject<'gc> {
activation: &mut Activation<'_, 'gc>,
gc_context: MutationContext<'gc, '_>,
name: Cow<str>,
callback: Executable<'gc>,
callback: Object<'gc>,
user_data: Value<'gc>,
) {
self.0.write(gc_context).watchers.insert(

View File

@ -337,7 +337,7 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
activation: &mut Activation<'_, 'gc>,
gc_context: MutationContext<'gc, '_>,
name: Cow<str>,
callback: Executable<'gc>,
callback: Object<'gc>,
user_data: Value<'gc>,
) {
self.0

View File

@ -242,7 +242,7 @@ impl<'gc> TObject<'gc> for SuperObject<'gc> {
_activation: &mut Activation<'_, 'gc>,
_gc_context: MutationContext<'gc, '_>,
_name: Cow<str>,
_callback: Executable<'gc>,
_callback: Object<'gc>,
_user_data: Value<'gc>,
) {
//`super` cannot have properties defined on it

View File

@ -162,7 +162,7 @@ impl<'gc> TObject<'gc> for XMLAttributesObject<'gc> {
activation: &mut Activation<'_, 'gc>,
gc_context: MutationContext<'gc, '_>,
name: Cow<str>,
callback: Executable<'gc>,
callback: Object<'gc>,
user_data: Value<'gc>,
) {
self.base()

View File

@ -160,7 +160,7 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> {
activation: &mut Activation<'_, 'gc>,
gc_context: MutationContext<'gc, '_>,
name: Cow<str>,
callback: Executable<'gc>,
callback: Object<'gc>,
user_data: Value<'gc>,
) {
self.base()