Bernd Kischnick
2009-Jul-08 22:31 UTC
[Swfdec] problems to lookup AS object properties using SWFDEC API functions
Hello list, I'm scratching my head over mysterious difficulties with variable lookup on Swfdec AS-objects inside the library. Neither swfdec_as_object_has_variable() nor swfdec_as_object_get_variable() nor swfdec_as_object_get_variable_and_flags() are able to find a property which definitely exists. In ActionScript, I'm doing this: var o = new Object (); o.foo = "bar"; o.observeValueForKeyPath = function () {...} I can enumerate this object from Actionscript: for (p in o) { trace("o["+p+"] = "+ o[p]); } and Swfdec reliably produces the correct trace output: o[foo] = bar o[observeValueForKeyPath]=[type Function] I can repeat this inside the library, given the pointer to the AS object: gboolean my_foreach (SwfdecAsObject *object, const char *variable, SwfdecAsValue *value, guint flags, gpointer data) { const char* val = swfdec_as_value_to_string (data, value); SWFDEC_ERROR("object @%p [%s] = @%p ('%s')", object, variable, value, val); return TRUE; } /* SwfdecAsContext *cx, SwfdecAsObject *object */ swfdec_as_object_foreach (object, my_foreach, cx); This way the properties 'foo' and 'observeValueForKeyPath' are found, additionally '__proto__' and '__constructor__'. But when I try to look up 'foo' or 'observeValueForKeyPath' using swfdec_as_object_has_variable(), swfdec_as_object_get_variable(), or swfdec_as_object_get_variable_and_flags() with parameter 'variable' set to the property name, neither of them succeeds. What am I doing wrong??? confused, - kisch
Bernd Kischnick
2009-Jul-09 11:13 UTC
[Swfdec] problems to lookup AS object properties using SWFDEC API functions - cause found
Replying to my own mail:> Neither > swfdec_as_object_has_variable() nor swfdec_as_object_get_variable() nor > swfdec_as_object_get_variable_and_flags() are able to find a property > which definitely exists....whereas enumerating the properties shows them to exist. This strange behaviour is caused by the properties-hash of AS objects being a DIRECT hash as opposed to a STRING hash. swfdec_as_object.c has this: static void swfdec_as_object_init (SwfdecAsObject *object) { object->properties = g_hash_table_new (g_direct_hash, g_direct_equal); } It should probably have g_str_hash and g_str_equal. Direct hashing only works as long as the property names are guaranteed to be the identical string constants (same address) as used when populating the hash. In my case I'm trying to look up a property using a fresh string constant as the key; this will never be address-equal to any existing key in the hash. Changing swfdec_as_object_init() to use g_str_hash and g_str_euqal seems to solve the lookup problem. Now I'm struggling to get AS function calls to work. Is there a reason why a direct hash was used in the first place? I hope the change doesn't have bad side effects. The lookup problem is probably masked by a backwards-compatibility mode for ActionScript < v7. In swfdec_as_object_hash_lookup(), there's a fallback to sequential case-insensitive property lookup when the direct lookup fails --- but my test SWF are v7, so the fallback wasn't effective. - kisch