[Swfdec] 2 commits - libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.h test/trace

Pekka Lampila medar at kemper.freedesktop.org
Fri Oct 26 02:32:55 PDT 2007


 libswfdec/swfdec_as_interpret.c   |   56 ++++++++++++++++++++++
 libswfdec/swfdec_as_object.h      |    1 
 test/trace/Makefile.am            |    9 +++
 test/trace/implements-5.swf       |binary
 test/trace/implements-5.swf.trace |   34 +++++++++++++
 test/trace/implements-6.swf       |binary
 test/trace/implements-6.swf.trace |   34 +++++++++++++
 test/trace/implements-7.swf       |binary
 test/trace/implements-7.swf.trace |   34 +++++++++++++
 test/trace/implements-8.swf       |binary
 test/trace/implements-8.swf.trace |   34 +++++++++++++
 test/trace/implements.as          |   95 ++++++++++++++++++++++++++++++++++++++
 12 files changed, 296 insertions(+), 1 deletion(-)

New commits:
commit e6964fd75fb2d0b95f533f67c753ef1e46ab837e
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri Oct 26 12:27:10 2007 +0300

    Add a test for Implements action

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 4a86d75..78767a2 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -789,6 +789,15 @@ EXTRA_DIST = \
 	instance-of-7.swf.trace \
 	instance-of-8.swf \
 	instance-of-8.swf.trace \
+	implements.as \
+	implements-5.swf \
+	implements-5.swf.trace \
+	implements-6.swf \
+	implements-6.swf.trace \
+	implements-7.swf \
+	implements-7.swf.trace \
+	implements-8.swf \
+	implements-8.swf.trace \
 	invalid-variable-name.as \
 	invalid-variable-name-5.swf \
 	invalid-variable-name-5.swf.trace \
diff --git a/test/trace/implements-5.swf b/test/trace/implements-5.swf
new file mode 100644
index 0000000..375286a
Binary files /dev/null and b/test/trace/implements-5.swf differ
diff --git a/test/trace/implements-5.swf.trace b/test/trace/implements-5.swf.trace
new file mode 100644
index 0000000..a9286c6
--- /dev/null
+++ b/test/trace/implements-5.swf.trace
@@ -0,0 +1,34 @@
+Test Implements ActionScript action
+A implements Array, XML
+Before
+true
+false
+false
+false
+test
+After
+true
+true
+true
+false
+B changes prototype to A.prototype
+Before
+false
+false
+false
+false
+After
+true
+true
+true
+false
+C has A as parent
+true
+true
+true
+false
+A.prototype is reset
+true
+false
+false
+false
diff --git a/test/trace/implements-6.swf b/test/trace/implements-6.swf
new file mode 100644
index 0000000..43869ef
Binary files /dev/null and b/test/trace/implements-6.swf differ
diff --git a/test/trace/implements-6.swf.trace b/test/trace/implements-6.swf.trace
new file mode 100644
index 0000000..a9286c6
--- /dev/null
+++ b/test/trace/implements-6.swf.trace
@@ -0,0 +1,34 @@
+Test Implements ActionScript action
+A implements Array, XML
+Before
+true
+false
+false
+false
+test
+After
+true
+true
+true
+false
+B changes prototype to A.prototype
+Before
+false
+false
+false
+false
+After
+true
+true
+true
+false
+C has A as parent
+true
+true
+true
+false
+A.prototype is reset
+true
+false
+false
+false
diff --git a/test/trace/implements-7.swf b/test/trace/implements-7.swf
new file mode 100644
index 0000000..c6d6028
Binary files /dev/null and b/test/trace/implements-7.swf differ
diff --git a/test/trace/implements-7.swf.trace b/test/trace/implements-7.swf.trace
new file mode 100644
index 0000000..a9286c6
--- /dev/null
+++ b/test/trace/implements-7.swf.trace
@@ -0,0 +1,34 @@
+Test Implements ActionScript action
+A implements Array, XML
+Before
+true
+false
+false
+false
+test
+After
+true
+true
+true
+false
+B changes prototype to A.prototype
+Before
+false
+false
+false
+false
+After
+true
+true
+true
+false
+C has A as parent
+true
+true
+true
+false
+A.prototype is reset
+true
+false
+false
+false
diff --git a/test/trace/implements-8.swf b/test/trace/implements-8.swf
new file mode 100644
index 0000000..653d731
Binary files /dev/null and b/test/trace/implements-8.swf differ
diff --git a/test/trace/implements-8.swf.trace b/test/trace/implements-8.swf.trace
new file mode 100644
index 0000000..a9286c6
--- /dev/null
+++ b/test/trace/implements-8.swf.trace
@@ -0,0 +1,34 @@
+Test Implements ActionScript action
+A implements Array, XML
+Before
+true
+false
+false
+false
+test
+After
+true
+true
+true
+false
+B changes prototype to A.prototype
+Before
+false
+false
+false
+false
+After
+true
+true
+true
+false
+C has A as parent
+true
+true
+true
+false
+A.prototype is reset
+true
+false
+false
+false
diff --git a/test/trace/implements.as b/test/trace/implements.as
new file mode 100644
index 0000000..90e95c5
--- /dev/null
+++ b/test/trace/implements.as
@@ -0,0 +1,95 @@
+// makeswf -v 7 -r 1 -o implements-7.swf implements.as
+
+trace ("Test Implements ActionScript action");
+
+
+trace ("A implements Array, XML");
+
+var A = function () {
+  return {
+    constructor: A,
+    __proto__: A.prototype
+  };
+};
+
+trace ("Before");
+var o = new A ();
+trace (o instanceOf A);
+trace (o instanceOf Array);
+trace (o instanceOf XML);
+trace (o instanceOf String);
+
+asm {
+  push "test"
+  push "Array"
+  getvariable
+  push "XML"
+  getvariable
+  push 2
+  push "A"
+  getvariable
+  implements
+  trace
+};
+
+trace ("After");
+var o = new A ();
+trace (o instanceOf A);
+trace (o instanceOf Array);
+trace (o instanceOf XML);
+trace (o instanceOf String);
+
+
+trace ("B changes prototype to A.prototype");
+var B = function () {
+  return {
+    constructor: B,
+    __proto__: B.prototype
+  };
+};
+
+trace ("Before");
+o = new B ();
+trace (o instanceOf A);
+trace (o instanceOf Array);
+trace (o instanceOf XML);
+trace (o instanceOf String);
+
+B.prototype = A.prototype;
+
+trace ("After");
+o = new B ();
+trace (o instanceOf A);
+trace (o instanceOf Array);
+trace (o instanceOf XML);
+trace (o instanceOf String);
+
+
+trace ("C has A as parent");
+var C = function () {
+  return {
+    constructor: C,
+    __proto__: C.prototype
+  };
+};
+C.prototype.__proto__ = A.prototype;
+
+o = new C ();
+trace (o instanceOf A);
+trace (o instanceOf Array);
+trace (o instanceOf XML);
+trace (o instanceOf String);
+
+
+trace ("A.prototype is reset");
+
+A.prototype = new Object ();
+
+var o = new A ();
+trace (o instanceOf A);
+trace (o instanceOf Array);
+trace (o instanceOf XML);
+trace (o instanceOf String);
+
+
+loadMovie ("FSCommand:quit", "");
commit 8e3fcac162910c84c950e1c45af41fb410d48df2
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri Oct 26 12:08:53 2007 +0300

    Implement Implements ActionScript action

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index e701ecf..1605a1a 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -2180,6 +2180,7 @@ swfdec_action_is_instance_of (SwfdecAsObject *object,
 {
   SwfdecAsValue val;
   SwfdecAsObject *class, *prototype;
+  GSList *iter;
 
   g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), FALSE);
   g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (constructor), FALSE);
@@ -2194,6 +2195,10 @@ swfdec_action_is_instance_of (SwfdecAsObject *object,
   while ((class = swfdec_as_object_get_prototype (class)) != NULL) {
     if (class == prototype)
       return TRUE;
+    for (iter = class->interfaces; iter != NULL; iter = iter->next) {
+      if (iter->data == prototype)
+	return TRUE;
+    }
   }
 
   return FALSE;
@@ -2264,6 +2269,55 @@ swfdec_action_cast (SwfdecAsContext *cx, guint action, const guint8 *data,
 }
 
 static void
+swfdec_action_implements (SwfdecAsContext *cx, guint action,
+    const guint8 *data, guint len)
+{
+  SwfdecAsValue *val, *argv;
+  SwfdecAsObject *object, *proto, *interface;
+  int argc, i;
+
+  swfdec_as_stack_ensure_size (cx, 2);
+
+  val = swfdec_as_stack_pop (cx);
+  if (SWFDEC_AS_VALUE_IS_OBJECT (val)) {
+    object = SWFDEC_AS_VALUE_GET_OBJECT (val);
+    swfdec_as_object_get_variable (object, SWFDEC_AS_STR_prototype, val);
+    if (SWFDEC_AS_VALUE_IS_OBJECT (val)) {
+      proto = SWFDEC_AS_VALUE_GET_OBJECT (val);
+    } else {
+      proto = NULL;
+    }
+  } else {
+    object = NULL;
+    proto = NULL;
+  }
+
+  val = swfdec_as_stack_pop (cx);
+  argc = swfdec_as_value_to_integer (cx, val);
+
+  if (argc > 0) {
+    swfdec_as_stack_ensure_size (cx, argc);
+    argv = swfdec_as_stack_pop_n (cx, argc);
+  } else {
+    argv = NULL;
+  }
+
+  if (proto == NULL)
+    return;
+
+  for (i = 0; i < argc; i++) {
+    if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[i]))
+      continue;
+    interface = SWFDEC_AS_VALUE_GET_OBJECT (&argv[i]);
+    swfdec_as_object_get_variable (interface, SWFDEC_AS_STR_prototype, val);
+    if (!SWFDEC_AS_VALUE_IS_OBJECT (val))
+      continue;
+    proto->interfaces =
+      g_slist_prepend (proto->interfaces, SWFDEC_AS_VALUE_GET_OBJECT (val));
+  }
+}
+
+static void
 swfdec_action_extends (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
   SwfdecAsValue *superclass, *subclass, proto;
@@ -2907,7 +2961,7 @@ const SwfdecActionSpec swfdec_as_actions[256] = {
   /* version 7 */
   [SWFDEC_AS_ACTION_THROW] = { "Throw", NULL },
   [SWFDEC_AS_ACTION_CAST] = { "Cast", NULL, 2, 1, { NULL, NULL, NULL, NULL, swfdec_action_cast } },
-  [SWFDEC_AS_ACTION_IMPLEMENTS] = { "Implements", NULL },
+  [SWFDEC_AS_ACTION_IMPLEMENTS] = { "Implements", NULL, -1, 0, { NULL, NULL, NULL, NULL, swfdec_action_implements } },
   /* version 4 */
   [0x30] = { "RandomNumber", NULL, 1, 1, { NULL, swfdec_action_random_number, swfdec_action_random_number, swfdec_action_random_number, swfdec_action_random_number } },
   [SWFDEC_AS_ACTION_MB_STRING_LENGTH] = { "MBStringLength", NULL },
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index 1877817..4fcddb4 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -65,6 +65,7 @@ struct _SwfdecAsObject {
   GHashTable *		watches;	/* string->WatchData mapping or NULL when not watching anything */
   guint8		flags;		/* GC flags */
   gsize			size;		/* size reserved in GC */
+  GSList *		interfaces;	/* list of interfaces this object implements */
 };
 
 struct _SwfdecAsObjectClass {


More information about the Swfdec mailing list