From a76ccebbb049fd8a55c170429be97967e73685ab Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Thu, 30 Oct 2008 23:33:33 +0100 Subject: [PATCH] make the set vfunc go away, too Now SwfdecAsObject has no more vfuncs, go us! --- swfdec/swfdec_as_object.c | 289 ++++++++++++++++++++++------------------------ swfdec/swfdec_as_object.h | 6 - swfdec/swfdec_movie.c | 28 +---- swfdec/swfdec_movie.h | 4 + 4 files changed, 145 insertions(+), 182 deletions(-) diff --git a/swfdec/swfdec_as_object.c b/swfdec/swfdec_as_object.c index 62a5ec58..3ecc7396 100644 --- a/swfdec/swfdec_as_object.c +++ b/swfdec/swfdec_as_object.c @@ -428,150 +428,6 @@ swfdec_as_object_hash_lookup_with_prototype (SwfdecAsObject *object, return var; } -#if 0 -static void -swfdec_as_array_set (SwfdecAsObject *object, const char *variable, - const SwfdecAsValue *val, guint flags) -{ -} -#endif - -static void -swfdec_as_object_do_set (SwfdecAsObject *object, const char *variable, - const SwfdecAsValue *val, guint flags) -{ - SwfdecAsVariable *var; - SwfdecAsWatch *watch; - SwfdecAsObject *proto; - SwfdecAsContext *context; - - if (!swfdec_as_variable_name_is_valid (variable) || - object->super) - return; - - context = swfdec_gc_object_get_context (object); - var = swfdec_as_object_hash_lookup_with_prototype (object, variable, &proto); - if (swfdec_as_context_is_aborted (context)) - return; - - // if variable is disabled in this version - if (var != NULL && !swfdec_as_object_variable_enabled_in_version (var, context->version)) { - if (proto == NULL) { - // it's at the top level, remove getter and setter plus overwrite - var->get = NULL; - var->set = NULL; - } else { - // it's in proto, we create a new one at the top level - var = NULL; - } - } - - if (var == NULL) { - var = swfdec_as_object_hash_create (object, variable, flags); - if (var == NULL) - return; - } else { - if (var->flags & SWFDEC_AS_VARIABLE_CONSTANT) - return; - // remove the flags that could make this variable hidden - if (context->version == 6) { - // version 6, so let's forget SWFDEC_AS_VARIABLE_VERSION_7_UP flag, oops! - // we will still set the value though, even if that flag is set - var->flags &= ~(SWFDEC_AS_VARIABLE_VERSION_6_UP | - SWFDEC_AS_VARIABLE_VERSION_NOT_6 | SWFDEC_AS_VARIABLE_VERSION_8_UP | - SWFDEC_AS_VARIABLE_VERSION_9_UP); - } else { - var->flags &= ~(SWFDEC_AS_VARIABLE_VERSION_6_UP | - SWFDEC_AS_VARIABLE_VERSION_NOT_6 | SWFDEC_AS_VARIABLE_VERSION_7_UP | - SWFDEC_AS_VARIABLE_VERSION_8_UP | SWFDEC_AS_VARIABLE_VERSION_9_UP); - } - } - if (object->watches) { - SwfdecAsValue ret = *val; - watch = g_hash_table_lookup (object->watches, variable); - /* FIXME: figure out if this limit here is correct. Add a watch in Flash 7 - * and set a variable using Flash 6 */ - if (watch && swfdec_as_watch_can_recurse (watch)) { - SwfdecAsValue args[4]; - SWFDEC_AS_VALUE_SET_STRING (&args[0], variable); - args[1] = var->value; - args[2] = *val; - args[3] = watch->watch_data; - swfdec_as_watch_ref (watch); - swfdec_as_function_call (watch->watch, object, 4, args, &ret); - swfdec_as_watch_unref (watch); - var = swfdec_as_object_hash_lookup_with_prototype (object, variable, - NULL); - if (swfdec_as_context_is_aborted (context)) - return; - if (var == NULL) { - SWFDEC_INFO ("watch removed variable %s", variable); - return; - } - } - - var->value = ret; - } else { - watch = NULL; - } - - if (object->array) { - /* if we changed to smaller length, destroy all values that are outside it */ - if (!swfdec_strcmp (context->version, variable, - SWFDEC_AS_STR_length)) - { - gint32 length_old = swfdec_as_array_get_length (object); - gint32 length_new = swfdec_as_value_to_integer (context, val); - length_new = MAX (0, length_new); - if (length_old > length_new) { - swfdec_as_array_remove_range (object, length_new, - length_old - length_new); - } - } - } - - if (var->get) { - if (var->set) { - SwfdecAsValue tmp; - swfdec_as_function_call (var->set, object, 1, val, &tmp); - } - } else if (watch == NULL) { - var->value = *val; - } - - if (variable == SWFDEC_AS_STR___proto__) { - if (SWFDEC_AS_VALUE_IS_OBJECT(val)) { - object->prototype = SWFDEC_AS_VALUE_GET_OBJECT (val); - object->prototype_flags = var->flags; - } else { - object->prototype = NULL; - object->prototype_flags = 0; - } - } - - /* If we are an array, do the special magic now */ - if (object->array) { - char *end; - gint32 l; - - /* if we added new value outside the current length, set a bigger length */ - l = strtoul (variable, &end, 10); - if (*end == '\0') { - SwfdecAsValue tmp; - gint32 length; - swfdec_as_object_get_variable (object, SWFDEC_AS_STR_length, &tmp); - length = swfdec_as_value_to_integer (context, &tmp); - if (l >= length) { - object->array = FALSE; - swfdec_as_value_set_integer (swfdec_gc_object_get_context (object), &tmp, l + 1); - swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR_length, &tmp, - SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT); - object->array = TRUE; - } - } - } -} - typedef struct { SwfdecAsObject * object; SwfdecAsVariableForeach func; @@ -713,8 +569,6 @@ swfdec_as_object_class_init (SwfdecAsObjectClass *klass) object_class->dispose = swfdec_as_object_dispose; gc_class->mark = swfdec_as_object_mark; - - klass->set = swfdec_as_object_do_set; } static void @@ -808,20 +662,157 @@ void swfdec_as_object_set_variable_and_flags (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *value, guint default_flags) { - SwfdecAsObjectClass *klass; + SwfdecAsVariable *var; + SwfdecAsWatch *watch; + SwfdecAsObject *proto; + SwfdecAsContext *context; g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); g_return_if_fail (variable != NULL); g_return_if_fail (SWFDEC_IS_AS_VALUE (value)); + context = swfdec_gc_object_get_context (object); + + /* FIXME: in front of or after debugger check? */ + if (!swfdec_as_variable_name_is_valid (variable) || + swfdec_as_context_is_aborted (context) || + object->super) + return; + if (swfdec_gc_object_get_context (object)->debugger) { SwfdecAsDebugger *debugger = swfdec_gc_object_get_context (object)->debugger; SwfdecAsDebuggerClass *dklass = SWFDEC_AS_DEBUGGER_GET_CLASS (debugger); if (dklass->set_variable) dklass->set_variable (debugger, swfdec_gc_object_get_context (object), object, variable, value); } - klass = SWFDEC_AS_OBJECT_GET_CLASS (object); - klass->set (object, variable, value, default_flags); + + if (object->movie) { + SwfdecMovie *movie = SWFDEC_MOVIE (object); + + guint prop_id = swfdec_movie_property_lookup (variable); + if (prop_id != G_MAXUINT) { + swfdec_movie_property_set (movie, prop_id, value); + return; + } + + swfdec_movie_call_variable_listeners (movie, variable, value); + } + + var = swfdec_as_object_hash_lookup_with_prototype (object, variable, &proto); + + // if variable is disabled in this version + if (var != NULL && !swfdec_as_object_variable_enabled_in_version (var, context->version)) { + if (proto == NULL) { + // it's at the top level, remove getter and setter plus overwrite + var->get = NULL; + var->set = NULL; + } else { + // it's in proto, we create a new one at the top level + var = NULL; + } + } + + if (var == NULL) { + var = swfdec_as_object_hash_create (object, variable, default_flags); + if (var == NULL) + return; + } else { + if (var->flags & SWFDEC_AS_VARIABLE_CONSTANT) + return; + // remove the flags that could make this variable hidden + if (context->version == 6) { + // version 6, so let's forget SWFDEC_AS_VARIABLE_VERSION_7_UP flag, oops! + // we will still set the value though, even if that flag is set + var->flags &= ~(SWFDEC_AS_VARIABLE_VERSION_6_UP | + SWFDEC_AS_VARIABLE_VERSION_NOT_6 | SWFDEC_AS_VARIABLE_VERSION_8_UP | + SWFDEC_AS_VARIABLE_VERSION_9_UP); + } else { + var->flags &= ~(SWFDEC_AS_VARIABLE_VERSION_6_UP | + SWFDEC_AS_VARIABLE_VERSION_NOT_6 | SWFDEC_AS_VARIABLE_VERSION_7_UP | + SWFDEC_AS_VARIABLE_VERSION_8_UP | SWFDEC_AS_VARIABLE_VERSION_9_UP); + } + } + if (object->watches) { + SwfdecAsValue ret = *value; + watch = g_hash_table_lookup (object->watches, variable); + /* FIXME: figure out if this limit here is correct. Add a watch in Flash 7 + * and set a variable using Flash 6 */ + if (watch && swfdec_as_watch_can_recurse (watch)) { + SwfdecAsValue args[4]; + SWFDEC_AS_VALUE_SET_STRING (&args[0], variable); + args[1] = var->value; + args[2] = *value; + args[3] = watch->watch_data; + swfdec_as_watch_ref (watch); + swfdec_as_function_call (watch->watch, object, 4, args, &ret); + swfdec_as_watch_unref (watch); + var = swfdec_as_object_hash_lookup_with_prototype (object, variable, NULL); + if (var == NULL) { + SWFDEC_INFO ("watch removed variable %s", variable); + return; + } + } + + var->value = ret; + } else { + watch = NULL; + } + + if (object->array) { + /* if we changed to smaller length, destroy all values that are outside it */ + if (!swfdec_strcmp (context->version, variable, + SWFDEC_AS_STR_length)) + { + gint32 length_old = swfdec_as_array_get_length (object); + gint32 length_new = swfdec_as_value_to_integer (context, value); + length_new = MAX (0, length_new); + if (length_old > length_new) { + swfdec_as_array_remove_range (object, length_new, + length_old - length_new); + } + } + } + + if (var->get) { + if (var->set) { + SwfdecAsValue tmp; + swfdec_as_function_call (var->set, object, 1, value, &tmp); + } + } else if (watch == NULL) { + var->value = *value; + } + + if (variable == SWFDEC_AS_STR___proto__) { + if (SWFDEC_AS_VALUE_IS_OBJECT(value)) { + object->prototype = SWFDEC_AS_VALUE_GET_OBJECT (value); + object->prototype_flags = var->flags; + } else { + object->prototype = NULL; + object->prototype_flags = 0; + } + } + + /* If we are an array, do the special magic now */ + if (object->array) { + char *end; + gint32 l; + + /* if we added new value outside the current length, set a bigger length */ + l = strtoul (variable, &end, 10); + if (*end == '\0') { + SwfdecAsValue tmp; + gint32 length; + swfdec_as_object_get_variable (object, SWFDEC_AS_STR_length, &tmp); + length = swfdec_as_value_to_integer (context, &tmp); + if (l >= length) { + object->array = FALSE; + swfdec_as_value_set_integer (swfdec_gc_object_get_context (object), &tmp, l + 1); + swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR_length, &tmp, + SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT); + object->array = TRUE; + } + } + } } /** diff --git a/swfdec/swfdec_as_object.h b/swfdec/swfdec_as_object.h index 8e9670c4..b388d9e0 100644 --- a/swfdec/swfdec_as_object.h +++ b/swfdec/swfdec_as_object.h @@ -73,12 +73,6 @@ struct _SwfdecAsObject { struct _SwfdecAsObjectClass { SwfdecGcObjectClass object_class; - - /* set the variable - and return it (or NULL on error) */ - void (* set) (SwfdecAsObject * object, - const char * variable, - const SwfdecAsValue * val, - guint default_flags); }; GType swfdec_as_object_get_type (void); diff --git a/swfdec/swfdec_movie.c b/swfdec/swfdec_movie.c index cbdc89a4..f4a91f77 100644 --- a/swfdec/swfdec_movie.c +++ b/swfdec/swfdec_movie.c @@ -1170,7 +1170,7 @@ swfdec_movie_remove_variable_listener (SwfdecMovie *movie, g_slist_remove (movie->variable_listeners, iter->data); } -static void +void swfdec_movie_call_variable_listeners (SwfdecMovie *movie, const char *name, const SwfdecAsValue *val) { @@ -1188,29 +1188,6 @@ swfdec_movie_call_variable_listeners (SwfdecMovie *movie, const char *name, } } -static void -swfdec_movie_set_variable (SwfdecAsObject *object, const char *variable, - const SwfdecAsValue *val, guint flags) -{ - SwfdecMovie *movie = SWFDEC_MOVIE (object); - guint prop_id; - - movie = swfdec_movie_resolve (movie); - if (movie == NULL) - return; - object = SWFDEC_AS_OBJECT (movie); - - prop_id = swfdec_movie_property_lookup (variable); - if (prop_id != G_MAXUINT) { - swfdec_movie_property_set (movie, prop_id, val); - return; - } - - swfdec_movie_call_variable_listeners (movie, variable, val); - - SWFDEC_AS_OBJECT_CLASS (swfdec_movie_parent_class)->set (object, variable, val, flags); -} - typedef struct { SwfdecMovie * movie; int depth; @@ -1365,7 +1342,6 @@ swfdec_movie_class_init (SwfdecMovieClass * movie_class) { GObjectClass *object_class = G_OBJECT_CLASS (movie_class); SwfdecGcObjectClass *gc_class = SWFDEC_GC_OBJECT_CLASS (movie_class); - SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (movie_class); object_class->constructor = swfdec_movie_constructor; object_class->dispose = swfdec_movie_dispose; @@ -1374,8 +1350,6 @@ swfdec_movie_class_init (SwfdecMovieClass * movie_class) gc_class->mark = swfdec_movie_mark; - asobject_class->set = swfdec_movie_set_variable; - signals[MATRIX_CHANGED] = g_signal_new ("matrix-changed", G_TYPE_FROM_CLASS (movie_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); diff --git a/swfdec/swfdec_movie.h b/swfdec/swfdec_movie.h index f00098a6..747e9121 100644 --- a/swfdec/swfdec_movie.h +++ b/swfdec/swfdec_movie.h @@ -232,6 +232,10 @@ void swfdec_movie_property_set (SwfdecMovie * movie, void swfdec_movie_property_get (SwfdecMovie * movie, guint id, SwfdecAsValue * val); +void swfdec_movie_call_variable_listeners + (SwfdecMovie * movie, + const char * name, + const SwfdecAsValue * val); void swfdec_movie_remove (SwfdecMovie * movie); void swfdec_movie_destroy (SwfdecMovie * movie); void swfdec_movie_set_static_properties -- 2.11.4.GIT