[Swfdec] Branch 'as' - 7 commits - libswfdec/swfdec_as_array.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_with.c libswfdec/swfdec_sprite_movie.c test/trace

Benjamin Otte company at kemper.freedesktop.org
Thu Jul 12 02:09:46 PDT 2007


 libswfdec/swfdec_as_array.c               |    8 ++++++--
 libswfdec/swfdec_as_frame.c               |    5 ++++-
 libswfdec/swfdec_as_interpret.c           |   13 +++++++++----
 libswfdec/swfdec_as_object.c              |   24 ++++++++++++++++++++++++
 libswfdec/swfdec_as_object.h              |    4 ++++
 libswfdec/swfdec_as_with.c                |    9 +++++++++
 libswfdec/swfdec_sprite_movie.c           |    9 +++++++--
 test/trace/Makefile.am                    |   18 ++++++++++++++++++
 test/trace/this-localfunction-5.swf       |binary
 test/trace/this-localfunction-5.swf.trace |    5 +++++
 test/trace/this-localfunction-6.swf       |binary
 test/trace/this-localfunction-6.swf.trace |    5 +++++
 test/trace/this-localfunction-7.swf       |binary
 test/trace/this-localfunction-7.swf.trace |    5 +++++
 test/trace/this-localfunction-8.swf       |binary
 test/trace/this-localfunction-8.swf.trace |    5 +++++
 test/trace/this-localfunction.as          |   20 ++++++++++++++++++++
 test/trace/with-outobject-5.swf           |binary
 test/trace/with-outobject-5.swf.trace     |    4 ++++
 test/trace/with-outobject-6.swf           |binary
 test/trace/with-outobject-6.swf.trace     |    4 ++++
 test/trace/with-outobject-7.swf           |binary
 test/trace/with-outobject-7.swf.trace     |    4 ++++
 test/trace/with-outobject-8.swf           |binary
 test/trace/with-outobject-8.swf.trace     |    4 ++++
 test/trace/with-outobject.as              |   17 +++++++++++++++++
 26 files changed, 154 insertions(+), 9 deletions(-)

New commits:
diff-tree d5f8ba68c26452741aba41ffc48e697e0aafe4b4 (from 853b7f4ee7c52323772f2c5482d36ceadf031c6c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Jul 12 11:09:36 2007 +0200

    add a test for With without an object

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 9511070..f15f8e7 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -889,6 +889,15 @@ EXTRA_DIST = \
 	with-function-delete-6.swf.trace \
 	with-function-delete-7.swf \
 	with-function-delete-7.swf.trace \
+	with-outobject.as \
+	with-outobject-5.swf \
+	with-outobject-5.swf.trace \
+	with-outobject-6.swf \
+	with-outobject-6.swf.trace \
+	with-outobject-7.swf \
+	with-outobject-7.swf.trace \
+	with-outobject-8.swf \
+	with-outobject-8.swf.trace \
 	with-prototypes.as \
 	with-prototypes-5.swf \
 	with-prototypes-5.swf.trace \
diff --git a/test/trace/with-outobject-5.swf b/test/trace/with-outobject-5.swf
new file mode 100644
index 0000000..0d8e4e0
Binary files /dev/null and b/test/trace/with-outobject-5.swf differ
diff --git a/test/trace/with-outobject-5.swf.trace b/test/trace/with-outobject-5.swf.trace
new file mode 100644
index 0000000..f37a654
--- /dev/null
+++ b/test/trace/with-outobject-5.swf.trace
@@ -0,0 +1,4 @@
+Check how with behaves when called on non-object values
+1
+...
+done
diff --git a/test/trace/with-outobject-6.swf b/test/trace/with-outobject-6.swf
new file mode 100644
index 0000000..8c31f85
Binary files /dev/null and b/test/trace/with-outobject-6.swf differ
diff --git a/test/trace/with-outobject-6.swf.trace b/test/trace/with-outobject-6.swf.trace
new file mode 100644
index 0000000..f37a654
--- /dev/null
+++ b/test/trace/with-outobject-6.swf.trace
@@ -0,0 +1,4 @@
+Check how with behaves when called on non-object values
+1
+...
+done
diff --git a/test/trace/with-outobject-7.swf b/test/trace/with-outobject-7.swf
new file mode 100644
index 0000000..a47abb9
Binary files /dev/null and b/test/trace/with-outobject-7.swf differ
diff --git a/test/trace/with-outobject-7.swf.trace b/test/trace/with-outobject-7.swf.trace
new file mode 100644
index 0000000..f37a654
--- /dev/null
+++ b/test/trace/with-outobject-7.swf.trace
@@ -0,0 +1,4 @@
+Check how with behaves when called on non-object values
+1
+...
+done
diff --git a/test/trace/with-outobject-8.swf b/test/trace/with-outobject-8.swf
new file mode 100644
index 0000000..6ec7bc4
Binary files /dev/null and b/test/trace/with-outobject-8.swf differ
diff --git a/test/trace/with-outobject-8.swf.trace b/test/trace/with-outobject-8.swf.trace
new file mode 100644
index 0000000..f37a654
--- /dev/null
+++ b/test/trace/with-outobject-8.swf.trace
@@ -0,0 +1,4 @@
+Check how with behaves when called on non-object values
+1
+...
+done
diff --git a/test/trace/with-outobject.as b/test/trace/with-outobject.as
new file mode 100644
index 0000000..2657ac5
--- /dev/null
+++ b/test/trace/with-outobject.as
@@ -0,0 +1,17 @@
+// makeswf -v 7 -s 200x150 -r 1 -o movie2.swf movie2.as
+
+trace ("Check how with behaves when called on non-object values");
+
+with ("hi") {
+  trace (indexOf ("i"));
+};
+with (undefined) {
+  trace ("undefined");
+};
+trace ("...");
+with (null) {
+  trace ("null");
+};
+trace ("done");
+
+loadMovie ("FSCommand:quit", "");
diff-tree 853b7f4ee7c52323772f2c5482d36ceadf031c6c (from fda2b0f04240de18304ad775d5ccea02a9f6437e)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Jul 12 11:07:24 2007 +0200

    With sections are skipped if the With doesn't reference an object

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 0c65e72..ae14f4f 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -2039,19 +2039,21 @@ static void
 swfdec_action_with (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
   SwfdecAsObject *object;
+  guint offset;
 
   if (len != 2) {
     SWFDEC_ERROR ("With action requires a length of 2, but got %u", len);
     swfdec_as_stack_pop (cx);
     return;
   }
+  offset = data[0] | (data[1] << 8);
   object = swfdec_as_value_to_object (cx, swfdec_as_stack_peek (cx, 1));
   if (object == NULL) {
-    SWFDEC_ERROR ("With called without an object");
-    swfdec_as_stack_pop (cx);
-    return;
+    SWFDEC_INFO ("With called without an object, skipping");
+    cx->frame->pc = (guint8 *) data + len + offset;
+  } else {
+    swfdec_as_with_new (object, data + len, offset);
   }
-  swfdec_as_with_new (object, data + len, GUINT16_FROM_LE (*(guint16 *) data));
   swfdec_as_stack_pop (cx);
 }
 
diff-tree fda2b0f04240de18304ad775d5ccea02a9f6437e (from f8b5b8a5f845885ed761592f5599ed331fbc9af0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Jul 12 11:03:15 2007 +0200

    Check that local functions get passed the Frame as this object

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index c2fc231..9511070 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -820,6 +820,15 @@ EXTRA_DIST = \
 	targetpath-6.swf.trace \
 	targetpath-7.swf \
 	targetpath-7.swf.trace \
+	this-localfunction.as \
+	this-localfunction-5.swf \
+	this-localfunction-5.swf.trace \
+	this-localfunction-6.swf \
+	this-localfunction-6.swf.trace \
+	this-localfunction-7.swf \
+	this-localfunction-7.swf.trace \
+	this-localfunction-8.swf \
+	this-localfunction-8.swf.trace \
 	tointeger-numbers.as \
 	tointeger-numbers-5.swf \
 	tointeger-numbers-5.swf.trace \
diff --git a/test/trace/this-localfunction-5.swf b/test/trace/this-localfunction-5.swf
new file mode 100644
index 0000000..886a34f
Binary files /dev/null and b/test/trace/this-localfunction-5.swf differ
diff --git a/test/trace/this-localfunction-5.swf.trace b/test/trace/this-localfunction-5.swf.trace
new file mode 100644
index 0000000..955adad
--- /dev/null
+++ b/test/trace/this-localfunction-5.swf.trace
@@ -0,0 +1,5 @@
+Check the this object of local functions
+[type Object]
+3
+[type Object]
+3
diff --git a/test/trace/this-localfunction-6.swf b/test/trace/this-localfunction-6.swf
new file mode 100644
index 0000000..68e9872
Binary files /dev/null and b/test/trace/this-localfunction-6.swf differ
diff --git a/test/trace/this-localfunction-6.swf.trace b/test/trace/this-localfunction-6.swf.trace
new file mode 100644
index 0000000..955adad
--- /dev/null
+++ b/test/trace/this-localfunction-6.swf.trace
@@ -0,0 +1,5 @@
+Check the this object of local functions
+[type Object]
+3
+[type Object]
+3
diff --git a/test/trace/this-localfunction-7.swf b/test/trace/this-localfunction-7.swf
new file mode 100644
index 0000000..f4e99eb
Binary files /dev/null and b/test/trace/this-localfunction-7.swf differ
diff --git a/test/trace/this-localfunction-7.swf.trace b/test/trace/this-localfunction-7.swf.trace
new file mode 100644
index 0000000..955adad
--- /dev/null
+++ b/test/trace/this-localfunction-7.swf.trace
@@ -0,0 +1,5 @@
+Check the this object of local functions
+[type Object]
+3
+[type Object]
+3
diff --git a/test/trace/this-localfunction-8.swf b/test/trace/this-localfunction-8.swf
new file mode 100644
index 0000000..c55475b
Binary files /dev/null and b/test/trace/this-localfunction-8.swf differ
diff --git a/test/trace/this-localfunction-8.swf.trace b/test/trace/this-localfunction-8.swf.trace
new file mode 100644
index 0000000..955adad
--- /dev/null
+++ b/test/trace/this-localfunction-8.swf.trace
@@ -0,0 +1,5 @@
+Check the this object of local functions
+[type Object]
+3
+[type Object]
+3
diff --git a/test/trace/this-localfunction.as b/test/trace/this-localfunction.as
new file mode 100644
index 0000000..d09652f
--- /dev/null
+++ b/test/trace/this-localfunction.as
@@ -0,0 +1,20 @@
+// makeswf -v 7 -s 200x150 -r 1 -o this-localfunction.swf this-localfunction.as
+
+trace ("Check the this object of local functions");
+
+function test () {
+  o = { x: 2 };
+  var x = 3;
+  var bla = function () {
+    trace (this);
+    trace (this.x);
+  };
+  bla ();
+  with (o) {
+    bla ();
+  }
+};
+x = 1;
+test ();
+
+loadMovie ("FSCommand:quit", "");
diff-tree f8b5b8a5f845885ed761592f5599ed331fbc9af0 (from 786973ef96469eef042e077378889e1303453930)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Jul 12 11:02:05 2007 +0200

    add swfdec_as_object_resolve()
    
    This is only used with the With object for now. I get the suspicion that With
    is handled differently in Flash. A lot of code could be removed by handling it
    different. I'd just find a nice way of getting the with stack into functions
    defined inside it.

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 6115cb5..5990d69 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -264,8 +264,11 @@ swfdec_as_frame_set_this (SwfdecAsFrame 
  * Finds the given variable in the current scope chain. Returns the first 
  * object in the scope chain that contains this variable in its prototype 
  * chain. If you want to know the explicit object that contains the variable,
- * you have to call swfdec_as_object_find_variable() on the result.
+ * you have to call swfdec_as_object_get_variable_and_flags() on the result.
  * If no such variable exist in the scope chain, %NULL is returned.
+ * <note>The returned object might be an internal object. You probably do not
+ * want to expose it to scripts. Call swfdec_as_object_resolve () on the
+ * returned value to be sure of not having an internal object.</note>
  *
  * Returns: the object that contains @variable or %NULL if none.
  **/
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 3f88deb..0c65e72 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -611,8 +611,9 @@ swfdec_action_call_function (SwfdecAsCon
   fun = swfdec_as_stack_peek (cx, 1);
   obj = swfdec_as_frame_find_variable (frame, name);
   if (obj) {
-    SWFDEC_AS_VALUE_SET_OBJECT (thisp, obj);
     swfdec_as_object_get_variable (obj, name, fun);
+    obj = swfdec_as_object_resolve (obj);
+    SWFDEC_AS_VALUE_SET_OBJECT (thisp, obj);
   } else {
     SWFDEC_AS_VALUE_SET_NULL (thisp);
     SWFDEC_AS_VALUE_SET_UNDEFINED (fun);
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index a18a4bc..3f81101 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -806,3 +806,27 @@ swfdec_as_object_get_debug (SwfdecAsObje
   return klass->debug (object);
 }
 
+/**
+ * swfdec_as_object_resolve:
+ * @object: a #SwfdecAsObject
+ *
+ * Resolves the object to its real object. Some internal objects should not be
+ * exposed to scripts, for example #SwfdecAsFrame objects. If an object you want
+ * to expose might be internal, call this function to resolve it to an object
+ * that is safe to expose.
+ *
+ * Returns: a non-internal object
+ **/
+SwfdecAsObject *
+swfdec_as_object_resolve (SwfdecAsObject *object)
+{
+  SwfdecAsObjectClass *klass;
+
+  g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL);
+
+  klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
+  if (klass->resolve == NULL)
+    return object;
+
+  return klass->resolve (object);
+}
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index 2c5c1c3..ef818fb 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -90,6 +90,9 @@ struct _SwfdecAsObjectClass {
   gboolean		(* foreach)		(SwfdecAsObject *	object,
 						 SwfdecAsVariableForeach func,
 						 gpointer		data);
+  /* get the real object referenced by this object (useful for internal objects) */
+  SwfdecAsObject *	(* resolve)		(SwfdecAsObject *	object);
+  /* get a debug string representation for this object */
   char *		(* debug)		(SwfdecAsObject *	object);
 };
 
@@ -104,6 +107,7 @@ void		swfdec_as_object_create		(SwfdecAs
 void		swfdec_as_object_set_constructor(SwfdecAsObject *	object,
 						 SwfdecAsObject *	construct,
 						 gboolean		scripted);
+SwfdecAsObject *swfdec_as_object_resolve	(SwfdecAsObject *	object);
 char *		swfdec_as_object_get_debug	(SwfdecAsObject *	object);
 
 void		swfdec_as_object_add		(SwfdecAsObject *     	object,
diff --git a/libswfdec/swfdec_as_with.c b/libswfdec/swfdec_as_with.c
index 9ef6c2e..9fe0720 100644
--- a/libswfdec/swfdec_as_with.c
+++ b/libswfdec/swfdec_as_with.c
@@ -38,6 +38,14 @@ swfdec_as_with_mark (SwfdecAsObject *obj
   SWFDEC_AS_OBJECT_CLASS (swfdec_as_with_parent_class)->mark (object);
 }
 
+static SwfdecAsObject *
+swfdec_as_with_resolve (SwfdecAsObject *object)
+{
+  SwfdecAsWith *with = SWFDEC_AS_WITH (object);
+
+  return with->object;
+}
+
 static gboolean
 swfdec_as_with_get (SwfdecAsObject *object, const char *variable,
   SwfdecAsValue *val, guint *flags)
@@ -96,6 +104,7 @@ swfdec_as_with_class_init (SwfdecAsWithC
   asobject_class->set_flags = swfdec_as_with_set_flags;
   asobject_class->delete = swfdec_as_with_delete;
   asobject_class->foreach = swfdec_as_with_foreach;
+  asobject_class->resolve = swfdec_as_with_resolve;
 }
 
 static void
diff-tree 786973ef96469eef042e077378889e1303453930 (from b26104d4c260fa0f05c08e79f6ab9ffb5671d0c8)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 11 23:42:17 2007 +0200

    pop the argument in error cases, too

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index e0777e4..3f88deb 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -2041,11 +2041,13 @@ swfdec_action_with (SwfdecAsContext *cx,
 
   if (len != 2) {
     SWFDEC_ERROR ("With action requires a length of 2, but got %u", len);
+    swfdec_as_stack_pop (cx);
     return;
   }
   object = swfdec_as_value_to_object (cx, swfdec_as_stack_peek (cx, 1));
   if (object == NULL) {
     SWFDEC_ERROR ("With called without an object");
+    swfdec_as_stack_pop (cx);
     return;
   }
   swfdec_as_with_new (object, data + len, GUINT16_FROM_LE (*(guint16 *) data));
diff-tree b26104d4c260fa0f05c08e79f6ab9ffb5671d0c8 (from 8e786dcd1797b334f791775772531c14d5c4cecb)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 11 21:45:33 2007 +0200

    fix memleak

diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index e2c535b..8bac537 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -299,7 +299,7 @@ swfdec_sprite_movie_perform_place (Swfde
   if (move) {
     if (cur == NULL) {
       SWFDEC_INFO ("no movie at depth %d, ignoring move command", depth);
-      return TRUE;
+      goto out;
     }
     if (graphic) {
       SwfdecMovieClass *klass = SWFDEC_MOVIE_GET_CLASS (cur);
@@ -311,10 +311,12 @@ swfdec_sprite_movie_perform_place (Swfde
   } else {
     if (cur != NULL && version > 5) {
       SWFDEC_INFO ("depth %d is already occupied by movie %s, not placing", depth, cur->name);
-      return TRUE;
+      goto out;
     }
     if (!SWFDEC_IS_GRAPHIC (graphic)) {
       SWFDEC_FIXME ("character %u is not a graphic (does it even exist?), aborting", id);
+      if (events)
+	swfdec_event_list_free (events);
       return FALSE;
     }
     cur = swfdec_movie_new (player, depth, mov, graphic, name);
@@ -328,6 +330,9 @@ swfdec_sprite_movie_perform_place (Swfde
     swfdec_movie_initialize (cur);
   }
 
+out:
+  if (events)
+    swfdec_event_list_free (events);
   return TRUE;
 }
 
diff-tree 8e786dcd1797b334f791775772531c14d5c4cecb (from dfcd46a62e9f98d291d4fe80187a1bed1b7a7212)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 11 20:02:01 2007 +0200

    speed up Array.join() and in turn Array.toString() by using a GString

diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c
index 60a13f5..c5070c8 100644
--- a/libswfdec/swfdec_as_array.c
+++ b/libswfdec/swfdec_as_array.c
@@ -368,16 +368,20 @@ swfdec_as_array_join (SwfdecAsContext *c
 
   length = swfdec_as_array_get_length (object);
   if (length > 0) {
+    /* FIXME: implement this with the StringBuilder class */
+    GString *string;
     var = swfdec_as_double_to_string (cx, 0);
     swfdec_as_object_get_variable (object, var, &val);
     str = swfdec_as_value_to_string (cx, &val);
+    string = g_string_new (str);
     for (i = 1; i < length; i++) {
       var = swfdec_as_double_to_string (cx, i);
       swfdec_as_object_get_variable (object, var, &val);
       var = swfdec_as_value_to_string (cx, &val);
-      str = swfdec_as_str_concat (cx, str, sep);
-      str = swfdec_as_str_concat (cx, str, var);
+      g_string_append (string, sep);
+      g_string_append (string, var);
     }
+    str = swfdec_as_context_give_string (cx, g_string_free (string, FALSE));
   } else {
     str = SWFDEC_AS_STR_EMPTY;
   }


More information about the Swfdec mailing list