[Swfdec] 2 commits - libswfdec/swfdec_as_array.c test/trace

Pekka Lampila medar at kemper.freedesktop.org
Fri Aug 17 04:26:47 PDT 2007


 libswfdec/swfdec_as_array.c   |  407 +++++++++++++++++++++++++-----------------
 test/trace/array2-5.swf       |binary
 test/trace/array2-5.swf.trace |   38 +++
 test/trace/array2-6.swf       |binary
 test/trace/array2-6.swf.trace |   38 +++
 test/trace/array2-7.swf       |binary
 test/trace/array2-7.swf.trace |   38 +++
 test/trace/array2.as          |   77 +++++++
 8 files changed, 437 insertions(+), 161 deletions(-)

New commits:
diff-tree c44ef5cc232c3bad04a9c5e86d0f501b93e2390f (from a41661fd62a2ed7ae083f3a9a583377991e20930)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri Aug 17 12:21:16 2007 +0300

    Add test on whether the arrays length is increased if it's negative and a value
    is inserted in bigger, but still negative index.

diff --git a/test/trace/array2-5.swf b/test/trace/array2-5.swf
index 4057223..803ccac 100644
Binary files a/test/trace/array2-5.swf and b/test/trace/array2-5.swf differ
diff --git a/test/trace/array2-5.swf.trace b/test/trace/array2-5.swf.trace
index d3221d7..d3081e8 100644
--- a/test/trace/array2-5.swf.trace
+++ b/test/trace/array2-5.swf.trace
@@ -42,6 +42,8 @@ undefined
 [, , , , , , , , , ]
 []
 []
+[]
+[]
 [[], [], [], , ]
 []
 [[], [], [], , ]
diff --git a/test/trace/array2-6.swf b/test/trace/array2-6.swf
index 42059f3..1d5c236 100644
Binary files a/test/trace/array2-6.swf and b/test/trace/array2-6.swf differ
diff --git a/test/trace/array2-6.swf.trace b/test/trace/array2-6.swf.trace
index 51dc019..bd63dd6 100644
--- a/test/trace/array2-6.swf.trace
+++ b/test/trace/array2-6.swf.trace
@@ -42,6 +42,8 @@ undefined
 [, , , , , , , , , ]
 []
 -4
+[]
+-1
 [1, b, c, , ]
 3.4
 [1, b, c, , ]
diff --git a/test/trace/array2-7.swf b/test/trace/array2-7.swf
index 1ceb5d9..e93a801 100644
Binary files a/test/trace/array2-7.swf and b/test/trace/array2-7.swf differ
diff --git a/test/trace/array2-7.swf.trace b/test/trace/array2-7.swf.trace
index 04a5849..e51c513 100644
--- a/test/trace/array2-7.swf.trace
+++ b/test/trace/array2-7.swf.trace
@@ -42,6 +42,8 @@ undefined
 [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]
 []
 -4
+[]
+-1
 [1, b, c, undefined, ]
 3.4
 [1, b, c, undefined, ]
diff --git a/test/trace/array2.as b/test/trace/array2.as
index bea9179..237a156 100644
--- a/test/trace/array2.as
+++ b/test/trace/array2.as
@@ -100,6 +100,11 @@ a = new Array (1, "b", "c", 4);		// nega
 a.length = -4;
 mytrace (a);
 mytrace (a.length);
+a = new Array ();			// setting negative variable while negative length
+a.length = -4;
+a[-2] = "x";
+mytrace (a);
+mytrace (a.length);
 a = new Array (1, "b", "c", 4);		// floating point values
 a.length = 3.4;
 mytrace (a);
@@ -116,7 +121,7 @@ a = new Array (1, "b", "c", 4);		// non-
 a.length = new Object ();
 mytrace (a);
 mytrace (a.length);
-a = new Array (1, "b", "c", 4);		// disabled until crash bug fixed
+a = new Array (1, "b", "c", 4);
 a.length = "har";
 mytrace (a);
 mytrace (a.length);
diff-tree a41661fd62a2ed7ae083f3a9a583377991e20930 (from bf81efebf34c71944530945a70c24532de6ea111)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri Aug 17 12:13:06 2007 +0300

    Make Array's method work with plain Objects.
    Fix push and pop methods to handle negative length values.
    Add test cases for both things.

diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c
index f6314a7..9d245c3 100644
--- a/libswfdec/swfdec_as_array.c
+++ b/libswfdec/swfdec_as_array.c
@@ -33,6 +33,7 @@
 #include "swfdec_as_native_function.h"
 #include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
+#include "swfdec_player_internal.h"
 
 G_DEFINE_TYPE (SwfdecAsArray, swfdec_as_array, SWFDEC_TYPE_AS_OBJECT)
 
@@ -73,7 +74,7 @@ swfdec_as_array_to_index (const char *st
 }
 
 static gint32
-swfdec_as_array_get_length (SwfdecAsObject *object)
+swfdec_as_array_get_length_as_integer (SwfdecAsObject *object)
 {
   SwfdecAsValue val;
   gint32 length;
@@ -83,6 +84,16 @@ swfdec_as_array_get_length (SwfdecAsObje
   swfdec_as_object_get_variable (object, SWFDEC_AS_STR_length, &val);
   length = swfdec_as_value_to_integer (object->context, &val);
 
+  return length;
+}
+
+static gint32
+swfdec_as_array_get_length (SwfdecAsObject *object)
+{
+  gint32 length;
+
+  length = swfdec_as_array_get_length_as_integer (object);
+
   if (length < 0)
     return 0;
 
@@ -105,7 +116,8 @@ typedef struct {
   gint32	num;
 } ForeachRemoveRangeData;
 
-static gboolean swfdec_as_array_foreach_remove_range (SwfdecAsObject *object,
+static gboolean
+swfdec_as_array_foreach_remove_range (SwfdecAsObject *object,
     const char *variable, SwfdecAsValue *value, guint flags, gpointer data)
 {
   ForeachRemoveRangeData *fdata = data;
@@ -122,7 +134,8 @@ static gboolean swfdec_as_array_foreach_
 }
 
 static void
-swfdec_as_array_remove_range (SwfdecAsArray *array, gint32 start_index, gint32 num)
+swfdec_as_array_remove_range (SwfdecAsArray *array, gint32 start_index,
+    gint32 num)
 {
   SwfdecAsObject *object = SWFDEC_AS_OBJECT (array);
 
@@ -140,7 +153,8 @@ swfdec_as_array_remove_range (SwfdecAsAr
     swfdec_as_object_delete_variable (object, var);
   } else {
     ForeachRemoveRangeData fdata = { start_index, num };
-    swfdec_as_object_foreach_remove (object, swfdec_as_array_foreach_remove_range, &fdata);
+    swfdec_as_object_foreach_remove (object,
+	swfdec_as_array_foreach_remove_range, &fdata);
   }
 }
 
@@ -151,8 +165,8 @@ typedef struct {
 } ForeachMoveRangeData;
 
 static const char *
-swfdec_as_array_foreach_move_range (SwfdecAsObject *object, const char *variable,
-    SwfdecAsValue *value, guint flags, gpointer data)
+swfdec_as_array_foreach_move_range (SwfdecAsObject *object,
+    const char *variable, SwfdecAsValue *value, guint flags, gpointer data)
 {
   ForeachMoveRangeData *fdata = data;
   gint32 idx;
@@ -172,12 +186,12 @@ swfdec_as_array_foreach_move_range (Swfd
 }
 
 static void
-swfdec_as_array_move_range (SwfdecAsArray *array, gint32 from_index, gint32 num, gint32 to_index)
+swfdec_as_array_move_range (SwfdecAsObject *object, gint32 from_index,
+    gint32 num, gint32 to_index)
 {
-  SwfdecAsObject *object = SWFDEC_AS_OBJECT (array);
   ForeachMoveRangeData fdata = { from_index, num, to_index };
 
-  g_return_if_fail (SWFDEC_IS_AS_ARRAY (array));
+  g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
   g_return_if_fail (from_index >= 0);
   g_return_if_fail (num >= 0);
   g_return_if_fail (from_index + num <= swfdec_as_array_get_length (object));
@@ -186,7 +200,8 @@ swfdec_as_array_move_range (SwfdecAsArra
   if (num == 0 || from_index == to_index)
     return;
 
-  swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_move_range, &fdata);
+  swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_move_range,
+      &fdata);
 
   // only changes length if it becomes bigger, not if it becomes smaller
   if (to_index + num > swfdec_as_array_get_length (object))
@@ -194,15 +209,14 @@ swfdec_as_array_move_range (SwfdecAsArra
 }
 
 static void
-swfdec_as_array_set_range (SwfdecAsArray *array, gint32 start_index, gint32 num,
-    const SwfdecAsValue *value)
+swfdec_as_array_set_range (SwfdecAsObject *object, gint32 start_index,
+    gint32 num, const SwfdecAsValue *value)
 {
-  SwfdecAsObject *object = SWFDEC_AS_OBJECT (array);
   gint32 i;
   const char *var;
 
-  g_return_if_fail (SWFDEC_IS_AS_ARRAY (array));
-  g_return_if_fail (start_index >= 0);
+  // allow negative indexes
+  g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
   g_return_if_fail (num >= 0);
   g_return_if_fail (value != NULL);
 
@@ -212,6 +226,15 @@ swfdec_as_array_set_range (SwfdecAsArray
   }
 }
 
+static void
+swfdec_as_array_append_internal (SwfdecAsObject *object, guint n,
+    const SwfdecAsValue *value)
+{
+  // allow negative length
+  swfdec_as_array_set_range (object,
+      swfdec_as_array_get_length_as_integer (object), n, value);
+}
+
 /**
  * swfdec_as_array_push:
  * @array: a #SwfdecAsArray
@@ -230,10 +253,12 @@ swfdec_as_array_set_range (SwfdecAsArray
  * Appends the given @values to the array.
  **/
 void
-swfdec_as_array_append (SwfdecAsArray *array, guint n, const SwfdecAsValue *value)
+swfdec_as_array_append (SwfdecAsArray *array, guint n,
+    const SwfdecAsValue *value)
 {
-  swfdec_as_array_set_range (array, swfdec_as_array_get_length (SWFDEC_AS_OBJECT (array)), n,
-    value);
+  // don't allow negative length
+  swfdec_as_array_set_range (SWFDEC_AS_OBJECT (array),
+      swfdec_as_array_get_length (SWFDEC_AS_OBJECT (array)), n, value);
 }
 
 typedef struct {
@@ -244,8 +269,8 @@ typedef struct {
 } ForeachAppendArrayRangeData;
 
 static gboolean
-swfdec_as_array_foreach_append_array_range (SwfdecAsObject *object, const char *variable,
-    SwfdecAsValue *value, guint flags, gpointer data)
+swfdec_as_array_foreach_append_array_range (SwfdecAsObject *object,
+    const char *variable, SwfdecAsValue *value, guint flags, gpointer data)
 {
   ForeachAppendArrayRangeData *fdata = data;
   gint32 idx;
@@ -262,16 +287,16 @@ swfdec_as_array_foreach_append_array_ran
 }
 
 static void
-swfdec_as_array_append_array_range (SwfdecAsArray *array_to, SwfdecAsArray *array_from,
-    gint32 start_index, gint32 num)
+swfdec_as_array_append_array_range (SwfdecAsArray *array_to,
+    SwfdecAsObject *object_from, gint32 start_index, gint32 num)
 {
-  SwfdecAsObject *object_from = SWFDEC_AS_OBJECT (array_from);
   ForeachAppendArrayRangeData fdata;
 
   g_return_if_fail (SWFDEC_IS_AS_ARRAY (array_to));
-  g_return_if_fail (SWFDEC_IS_AS_ARRAY (array_from));
+  g_return_if_fail (SWFDEC_IS_AS_OBJECT (object_from));
   g_return_if_fail (start_index >= 0);
-  g_return_if_fail (start_index + num <= swfdec_as_array_get_length (object_from));
+  g_return_if_fail (
+      start_index + num <= swfdec_as_array_get_length (object_from));
 
   if (num == 0)
     return;
@@ -282,14 +307,15 @@ swfdec_as_array_append_array_range (Swfd
   fdata.num = num;
 
   swfdec_as_array_set_length (fdata.object_to, fdata.offset + fdata.num);
-  swfdec_as_object_foreach (object_from, swfdec_as_array_foreach_append_array_range, &fdata);
+  swfdec_as_object_foreach (object_from,
+      swfdec_as_array_foreach_append_array_range, &fdata);
 }
 
 static void
-swfdec_as_array_append_array (SwfdecAsArray *array_to, SwfdecAsArray *array_from)
+swfdec_as_array_append_array (SwfdecAsArray *array_to, SwfdecAsObject *object_from)
 {
-  swfdec_as_array_append_array_range (array_to, array_from, 0,
-      swfdec_as_array_get_length (SWFDEC_AS_OBJECT (array_from)));
+  swfdec_as_array_append_array_range (array_to, object_from, 0,
+      swfdec_as_array_get_length (object_from));
 }
 
 /*
@@ -297,14 +323,6 @@ swfdec_as_array_append_array (SwfdecAsAr
  */
 
 static void
-swfdec_as_array_dispose (GObject *object)
-{
-  //SwfdecAsArray *array = SWFDEC_AS_ARRAY (object);
-
-  G_OBJECT_CLASS (swfdec_as_array_parent_class)->dispose (object);
-}
-
-static void
 swfdec_as_array_add (SwfdecAsObject *object)
 {
   swfdec_as_array_set_length (object, 0);
@@ -313,39 +331,42 @@ swfdec_as_array_add (SwfdecAsObject *obj
 }
 
 static void
-swfdec_as_array_set (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *val)
+swfdec_as_array_set (SwfdecAsObject *object, const char *variable,
+    const SwfdecAsValue *val)
 {
-  gint32 l = swfdec_as_array_to_index (variable);
+  char *end;
+  gboolean indexvar = TRUE;
+  gint32 l = strtoul (variable, &end, 10);
+
+  if (*end != 0 || l > G_MAXINT32)
+    indexvar = FALSE;
 
   // if we changed to smaller length, destroy all values that are outside it
   if (!strcmp (variable, SWFDEC_AS_STR_length)) {
     gint32 length_old = swfdec_as_array_get_length (object);
-    gint32 length_new = MAX (0, swfdec_as_value_to_integer (object->context, val));
-    if (length_old > length_new)
-      swfdec_as_array_remove_range (SWFDEC_AS_ARRAY (object), length_new, length_old - length_new);
+    gint32 length_new = MAX (0,
+	swfdec_as_value_to_integer (object->context, val));
+    if (length_old > length_new) {
+      swfdec_as_array_remove_range (SWFDEC_AS_ARRAY (object), length_new,
+	  length_old - length_new);
+    }
   }
 
-  SWFDEC_AS_OBJECT_CLASS (swfdec_as_array_parent_class)->set (object, variable, val);
+  SWFDEC_AS_OBJECT_CLASS (swfdec_as_array_parent_class)->set (object, variable,
+      val);
 
   // if we added new value outside the current length, set a bigger length
-  if (l > -1) {
-    int cur;
-    l++;
-    cur = swfdec_as_array_get_length (object);
-    if (l > cur) {
+  if (indexvar) {
+    if (++l > swfdec_as_array_get_length_as_integer (object))
       swfdec_as_array_set_length (object, l);
-    }
   }
 }
 
 static void
 swfdec_as_array_class_init (SwfdecAsArrayClass *klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
   SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass);
 
-  object_class->dispose = swfdec_as_array_dispose;
-
   asobject_class->add = swfdec_as_array_add;
   asobject_class->set = swfdec_as_array_set;
 }
@@ -374,7 +395,7 @@ swfdec_as_array_new (SwfdecAsContext *co
 
   g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
   g_return_val_if_fail (context->Array != NULL, NULL);
-  
+
   if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsArray)))
     return FALSE;
   ret = g_object_new (SWFDEC_TYPE_AS_ARRAY, NULL);
@@ -385,9 +406,10 @@ swfdec_as_array_new (SwfdecAsContext *co
 
 /*** AS CODE ***/
 
-static void
-swfdec_as_array_join (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc, SwfdecAsValue *argv,
-    SwfdecAsValue *ret)
+SWFDEC_AS_NATIVE (252, 7, swfdec_as_array_join)
+void
+swfdec_as_array_join (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
+    SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   int i, length;
   const char *var, *str, *sep;
@@ -422,66 +444,84 @@ swfdec_as_array_join (SwfdecAsContext *c
   SWFDEC_AS_VALUE_SET_STRING (ret, str);
 }
 
-static void
-swfdec_as_array_toString (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
-    SwfdecAsValue *argv, SwfdecAsValue *ret)
+SWFDEC_AS_NATIVE (252, 9, swfdec_as_array_toString)
+void
+swfdec_as_array_toString (SwfdecAsContext *cx, SwfdecAsObject *object,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   swfdec_as_array_join (cx, object, 0, NULL, ret);
 }
 
-static void
-swfdec_as_array_do_push (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
-    SwfdecAsValue *argv, SwfdecAsValue *ret)
+SWFDEC_AS_NATIVE (252, 1, swfdec_as_array_do_push)
+void
+swfdec_as_array_do_push (SwfdecAsContext *cx, SwfdecAsObject *object,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  SwfdecAsArray *array = SWFDEC_AS_ARRAY (object);
-
-  // we allow calling with 0 args, so that we'll return the length even in that case
-  if (argc > 0)
-    swfdec_as_array_append (array, argc, argv);
+  // if 0 args, just return the length
+  // manually set the length here to make the function work on non-Arrays
+  if (argc > 0) {
+    gint32 length = swfdec_as_array_get_length_as_integer (object);
+    swfdec_as_array_append_internal (object, argc, argv);
+    swfdec_as_array_set_length (object, length + argc);
+  }
 
-  SWFDEC_AS_VALUE_SET_INT (ret, swfdec_as_array_get_length (object));
+  SWFDEC_AS_VALUE_SET_INT (ret, swfdec_as_array_get_length_as_integer (object));
 }
 
-static void
+SWFDEC_AS_NATIVE (252, 2, swfdec_as_array_do_pop)
+void
 swfdec_as_array_do_pop (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
     SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   gint32 length;
   const char *var;
 
-  length = swfdec_as_array_get_length (object);
-  if (length <= 0)
+  // we allow negative indexes here, but not 0
+  length = swfdec_as_array_get_length_as_integer (object);
+  if (length == 0)
     return;
 
   var = swfdec_as_double_to_string (object->context, length - 1);
   swfdec_as_object_get_variable (object, var, ret);
-  swfdec_as_array_set_length (object, length - 1);
+
+  // if Array, the length is reduced by one (which destroys the variable also)
+  // else the length is not reduced at all, but the variable is still deleted
+  if (SWFDEC_IS_AS_ARRAY (object)) {
+    swfdec_as_array_set_length (object, length - 1);
+  } else {
+    swfdec_as_object_delete_variable (object, var);
+  }
 }
 
-static void
-swfdec_as_array_do_unshift (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
-    SwfdecAsValue *argv, SwfdecAsValue *ret)
+SWFDEC_AS_NATIVE (252, 5, swfdec_as_array_do_unshift)
+void
+swfdec_as_array_do_unshift (SwfdecAsContext *cx, SwfdecAsObject *object,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  SwfdecAsArray *array = SWFDEC_AS_ARRAY (object);
   gint32 length;
 
   if (argc) {
+    // don't allow negative length
     length = swfdec_as_array_get_length (object);
-    swfdec_as_array_move_range (array, 0, length, argc);
-    swfdec_as_array_set_range (array, 0, argc, argv);
+    swfdec_as_array_move_range (object, 0, length, argc);
+    swfdec_as_array_set_range (object, 0, argc, argv);
+    // if not Array, leave the length unchanged
+    if (!SWFDEC_IS_AS_ARRAY (object))
+      swfdec_as_array_set_length (object, length);
   }
 
   SWFDEC_AS_VALUE_SET_INT (ret, swfdec_as_array_get_length (object));
 }
 
-static void
-swfdec_as_array_do_shift (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
-    SwfdecAsValue *argv, SwfdecAsValue *ret)
+SWFDEC_AS_NATIVE (252, 4, swfdec_as_array_do_shift)
+void
+swfdec_as_array_do_shift (SwfdecAsContext *cx, SwfdecAsObject *object,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  SwfdecAsArray *array = SWFDEC_AS_ARRAY (object);
   gint32 length;
   const char *var;
 
+  // don't allow negative length
   length = swfdec_as_array_get_length (object);
   if (length <= 0)
     return;
@@ -489,8 +529,23 @@ swfdec_as_array_do_shift (SwfdecAsContex
   var = swfdec_as_double_to_string (object->context, 0);
   swfdec_as_object_get_variable (object, var, ret);
 
-  swfdec_as_array_move_range (array, 1, length - 1, 0);
-  swfdec_as_array_set_length (object, length - 1);
+  swfdec_as_array_move_range (object, 1, length - 1, 0);
+
+  // if not Array, leave the length unchanged, and don't remove the element
+  if (SWFDEC_IS_AS_ARRAY (object)) {
+    swfdec_as_array_set_length (object, length - 1);
+  } else {
+    // we have to put the last element back, because we used move, not copy
+    SwfdecAsValue val;
+    if (length > 1) {
+      var = swfdec_as_double_to_string (object->context, length - 2);
+      swfdec_as_object_get_variable (object, var, &val);
+    } else {
+      val = *ret;
+    }
+    var = swfdec_as_double_to_string (object->context, length - 1);
+    swfdec_as_object_set_variable (object, var, &val);
+  }
 }
 
 static const char *
@@ -507,19 +562,22 @@ swfdec_as_array_foreach_reverse (SwfdecA
   return swfdec_as_double_to_string (object->context, *length - 1 - idx);
 }
 
-static void
-swfdec_as_array_reverse (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
-    SwfdecAsValue *argv, SwfdecAsValue *ret)
+SWFDEC_AS_NATIVE (252, 11, swfdec_as_array_reverse)
+void
+swfdec_as_array_reverse (SwfdecAsContext *cx, SwfdecAsObject *object,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   gint32 length;
 
   length = swfdec_as_array_get_length (object);
-  swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_reverse, &length);
+  swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_reverse,
+      &length);
 
   SWFDEC_AS_VALUE_SET_OBJECT (ret, object);
 }
 
-static void
+SWFDEC_AS_NATIVE (252, 3, swfdec_as_array_concat)
+void
 swfdec_as_array_concat (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
     SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
@@ -531,18 +589,19 @@ swfdec_as_array_concat (SwfdecAsContext 
   object_new = swfdec_as_array_new (cx);
   array_new = SWFDEC_AS_ARRAY (object_new);
 
-  swfdec_as_array_append_array (array_new, SWFDEC_AS_ARRAY (object));
+  swfdec_as_array_append_array (array_new, object);
 
   for (j = 0; j < argc; j++) {
     if (SWFDEC_AS_VALUE_IS_OBJECT (&argv[j]) &&
 	SWFDEC_IS_AS_ARRAY (SWFDEC_AS_VALUE_GET_OBJECT (&argv[j])))
     {
       swfdec_as_array_append_array (array_new,
-	  SWFDEC_AS_ARRAY (SWFDEC_AS_VALUE_GET_OBJECT (&argv[j])));
+	  SWFDEC_AS_VALUE_GET_OBJECT (&argv[j]));
     }
     else
     {
-      var = swfdec_as_double_to_string (object->context, swfdec_as_array_get_length (object_new));
+      var = swfdec_as_double_to_string (object->context,
+	  swfdec_as_array_get_length (object_new));
       swfdec_as_object_set_variable (object_new, var, &argv[j]);
     }
   }
@@ -550,7 +609,8 @@ swfdec_as_array_concat (SwfdecAsContext 
   SWFDEC_AS_VALUE_SET_OBJECT (ret, object_new);
 }
 
-static void
+SWFDEC_AS_NATIVE (252, 6, swfdec_as_array_slice)
+void
 swfdec_as_array_slice (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
     SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
@@ -582,16 +642,16 @@ swfdec_as_array_slice (SwfdecAsContext *
   object_new = swfdec_as_array_new (cx);
   array_new = SWFDEC_AS_ARRAY (object_new);
 
-  swfdec_as_array_append_array_range (array_new, SWFDEC_AS_ARRAY (object), start_index, num);
+  swfdec_as_array_append_array_range (array_new, object, start_index, num);
 
   SWFDEC_AS_VALUE_SET_OBJECT (ret, object_new);
 }
 
-static void
+SWFDEC_AS_NATIVE (252, 8, swfdec_as_array_splice)
+void
 swfdec_as_array_splice (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
     SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  SwfdecAsArray *array = SWFDEC_AS_ARRAY (object);
   gint32 length, start_index, num_remove, num_add;
   SwfdecAsObject *object_new;
   SwfdecAsArray *array_new;
@@ -608,7 +668,8 @@ swfdec_as_array_splice (SwfdecAsContext 
   }
 
   if (argc > 1) {
-    num_remove = CLAMP (swfdec_as_value_to_integer (cx, &argv[1]), 0, length - start_index);
+    num_remove = CLAMP (swfdec_as_value_to_integer (cx, &argv[1]), 0,
+	length - start_index);
   } else {
     num_remove = length - start_index;
   }
@@ -618,13 +679,14 @@ swfdec_as_array_splice (SwfdecAsContext 
   object_new = swfdec_as_array_new (cx);
   array_new = SWFDEC_AS_ARRAY (object_new);
 
-  swfdec_as_array_append_array_range (array_new, array, start_index, num_remove);
-  swfdec_as_array_move_range (array, start_index + num_remove, length - (start_index + num_remove),
-      start_index + num_add);
+  swfdec_as_array_append_array_range (array_new, object, start_index,
+      num_remove);
+  swfdec_as_array_move_range (object, start_index + num_remove,
+      length - (start_index + num_remove), start_index + num_add);
   if (num_remove > num_add)
     swfdec_as_array_set_length (object, length - (num_remove - num_add));
   if (argc > 2)
-    swfdec_as_array_set_range (array, start_index, argc - 2, argv + 2);
+    swfdec_as_array_set_range (object, start_index, argc - 2, argv + 2);
 
   SWFDEC_AS_VALUE_SET_OBJECT (ret, object_new);
 }
@@ -651,8 +713,8 @@ typedef struct {
 } ForeachSortData;
 
 static gint
-swfdec_as_array_sort_compare (SwfdecAsContext *cx, SwfdecAsValue *a, SwfdecAsValue *b,
-    gint32 options, SwfdecAsFunction *fun)
+swfdec_as_array_sort_compare (SwfdecAsContext *cx, SwfdecAsValue *a,
+    SwfdecAsValue *b, gint32 options, SwfdecAsFunction *fun)
 {
   gint retval;
 
@@ -680,11 +742,13 @@ swfdec_as_array_sort_compare (SwfdecAsCo
   }
   else if (options & ARRAY_SORT_OPTION_CASEINSENSITIVE)
   {
-    retval = g_strcasecmp (swfdec_as_value_to_string (cx, a), swfdec_as_value_to_string (cx, b));
+    retval = g_strcasecmp (swfdec_as_value_to_string (cx, a),
+	swfdec_as_value_to_string (cx, b));
   }
   else
   {
-    retval = strcmp (swfdec_as_value_to_string (cx, a), swfdec_as_value_to_string (cx, b));
+    retval = strcmp (swfdec_as_value_to_string (cx, a),
+	swfdec_as_value_to_string (cx, b));
   }
 
   if (options & ARRAY_SORT_OPTION_DESCENDING) {
@@ -696,8 +760,8 @@ swfdec_as_array_sort_compare (SwfdecAsCo
 
 // renames values in the array based on fdata->order values
 static const char *
-swfdec_as_array_foreach_sort_rename (SwfdecAsObject *object, const char *variable,
-    SwfdecAsValue *value, guint flags, gpointer data)
+swfdec_as_array_foreach_sort_rename (SwfdecAsObject *object,
+    const char *variable, SwfdecAsValue *value, guint flags, gpointer data)
 {
   ForeachSortData *fdata = data;
   gint32 idx, i;
@@ -728,7 +792,8 @@ swfdec_as_array_foreach_sort_rename (Swf
 }
 
 // fills fdata->object_new array using indexes based on the fdata->order
-static gboolean swfdec_as_array_foreach_sort_indexedarray (SwfdecAsObject *object,
+static gboolean
+swfdec_as_array_foreach_sort_indexedarray (SwfdecAsObject *object,
     const char *variable, SwfdecAsValue *value, guint flags, gpointer data)
 {
   ForeachSortData *fdata = data;
@@ -767,7 +832,8 @@ static gboolean swfdec_as_array_foreach_
 // sets undefined values in the fdata->object_new array to indexes of undefined
 // values in the object array
 static void
-swfdec_as_array_sort_set_undefined_indexedarray (SwfdecAsObject *object, ForeachSortData *fdata)
+swfdec_as_array_sort_set_undefined_indexedarray (SwfdecAsObject *object,
+    ForeachSortData *fdata)
 {
   SwfdecAsValue val;
   const char *var;
@@ -795,8 +861,8 @@ swfdec_as_array_sort_set_undefined_index
 // (in the sense that sorting compare function returns 0)
 // used by uniquesort when there is exactly one undefined value in the array
 static gboolean
-swfdec_as_array_foreach_sort_compare_undefined (SwfdecAsObject *object, const char *variable,
-    SwfdecAsValue *value, guint flags, gpointer data)
+swfdec_as_array_foreach_sort_compare_undefined (SwfdecAsObject *object,
+    const char *variable, SwfdecAsValue *value, guint flags, gpointer data)
 {
   ForeachSortData *fdata = data;
   gint32 idx;
@@ -811,15 +877,16 @@ swfdec_as_array_foreach_sort_compare_und
   fdata->defined_values++;
 
   // when testing for uniquesort the custom compare function is NOT used
-  if (swfdec_as_array_sort_compare (object->context, value, &fdata->undefined, fdata->options, NULL) == 0)
+  if (swfdec_as_array_sort_compare (object->context, value, &fdata->undefined,
+	fdata->options, NULL) == 0)
     return FALSE;
 
   return TRUE;
 }
 
 static gboolean
-swfdec_as_array_foreach_sort_populate (SwfdecAsObject *object, const char *variable,
-    SwfdecAsValue *value, guint flags, gpointer data)
+swfdec_as_array_foreach_sort_populate (SwfdecAsObject *object,
+    const char *variable, SwfdecAsValue *value, guint flags, gpointer data)
 {
   ForeachSortData *fdata = data;
   gint32 idx, i;
@@ -837,15 +904,18 @@ swfdec_as_array_foreach_sort_populate (S
   // find the position for this value
   for (i = 0; i < fdata->order_size; i++)
   {
-    if (fdata->order[i] == NULL || (cval = swfdec_as_array_sort_compare (object->context, value, fdata->order[i], fdata->options, fdata->compare_custom_func)) <= 0)
+    if (fdata->order[i] == NULL ||
+	(cval = swfdec_as_array_sort_compare (object->context, value,
+	    fdata->order[i], fdata->options, fdata->compare_custom_func)) <= 0)
     {
       SwfdecAsValue *tmp2, *tmp;
 
-      // if we are doing uniquesort, see if this value is the same as some earlier value
+      // if we are doing uniquesort, see if this value is the same as some
+      // earlier value
       if (fdata->options & ARRAY_SORT_OPTION_UNIQUESORT && fdata->order[i] != NULL &&
 	  fdata->order[i] != &fdata->undefined) {
-	// when using custom function, uniquesort is still based on the equality given by
-	// the normal method, not the custom function
+	// when using custom function, uniquesort is still based on the
+	// equality given by the normal method, not the custom function
 	if (fdata->compare_custom_func != NULL) {
 	  if (swfdec_as_array_sort_compare (object->context, value, fdata->order[i], fdata->options, NULL) == 0)
 	    return FALSE;
@@ -872,7 +942,8 @@ swfdec_as_array_foreach_sort_populate (S
   return TRUE;
 }
 
-static void
+SWFDEC_AS_NATIVE (252, 10, swfdec_as_array_sort)
+void
 swfdec_as_array_sort (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
     SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
@@ -880,7 +951,8 @@ swfdec_as_array_sort (SwfdecAsContext *c
   guint pos;
 
   fdata.length = swfdec_as_array_get_length (object);
-  fdata.order_size = MIN ((gint32)g_hash_table_size (object->properties) + 1, fdata.length + 1);
+  fdata.order_size =
+    MIN ((gint32)g_hash_table_size (object->properties) + 1, fdata.length + 1);
   fdata.order = g_new0 (SwfdecAsValue *, fdata.order_size);
   SWFDEC_AS_VALUE_SET_UNDEFINED (&fdata.undefined);
   fdata.order[0] = &fdata.undefined;
@@ -890,7 +962,8 @@ swfdec_as_array_sort (SwfdecAsContext *c
   if (argc > 0 && !SWFDEC_AS_VALUE_IS_NUMBER (&argv[0])) {
     SwfdecAsFunction *fun;
     if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[0]) ||
-	!SWFDEC_IS_AS_FUNCTION (fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&argv[0])))
+	!SWFDEC_IS_AS_FUNCTION (
+	  fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&argv[0])))
 	return;
     fdata.compare_custom_func = fun;
     pos++;
@@ -905,24 +978,31 @@ swfdec_as_array_sort (SwfdecAsContext *c
   }
 
   // generate fdata.order which points to the values
-  if (!swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_populate, &fdata)) {
+  if (!swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_populate,
+	&fdata))
+  {
     // uniquesort failed
     SWFDEC_AS_VALUE_SET_INT (ret, 0);
     g_free (fdata.order);
     return;
   }
 
-  if (fdata.options & ARRAY_SORT_OPTION_UNIQUESORT && fdata.defined_values + 1 < fdata.length) {
+  if (fdata.options & ARRAY_SORT_OPTION_UNIQUESORT &&
+      fdata.defined_values + 1 < fdata.length)
+  {
     // uniquesort fails, because we have more than one undefined value
     SWFDEC_AS_VALUE_SET_INT (ret, 0);
     g_free (fdata.order);
     return;
   }
 
-  if (fdata.options & ARRAY_SORT_OPTION_UNIQUESORT && fdata.defined_values < fdata.length) {
-    // uniquesort used, and we have atleast one undefined value
-    // test if anything equeals to that
-    if (!swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_compare_undefined, &fdata))
+  if (fdata.options & ARRAY_SORT_OPTION_UNIQUESORT &&
+      fdata.defined_values < fdata.length)
+  {
+    // uniquesort used, and we have exactly one undefined value test if
+    // anything equeals to that
+    if (!swfdec_as_object_foreach (object,
+	  swfdec_as_array_foreach_sort_compare_undefined, &fdata))
     {
       SWFDEC_AS_VALUE_SET_INT (ret, 0);
       g_free (fdata.order);
@@ -933,20 +1013,23 @@ swfdec_as_array_sort (SwfdecAsContext *c
   if (fdata.options & ARRAY_SORT_OPTION_RETURNINDEXEDARRAY) {
     // make a new array and fill it with numbers based on the order
     fdata.object_new = swfdec_as_array_new (cx);
-    swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_indexedarray, &fdata);
-    // we only have the elements that have been set so far, so fill in the blanks
+    swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_indexedarray,
+       &fdata);
+    // we only have the elements that have been set so far, fill in the blanks
     swfdec_as_array_sort_set_undefined_indexedarray (object, &fdata);
     SWFDEC_AS_VALUE_SET_OBJECT (ret, fdata.object_new);
   } else {
     // rename properties based on the new order
-    swfdec_as_object_foreach_rename (object, swfdec_as_array_foreach_sort_rename, &fdata);
+    swfdec_as_object_foreach_rename (object,
+	swfdec_as_array_foreach_sort_rename, &fdata);
     SWFDEC_AS_VALUE_SET_OBJECT (ret, object);
   }
 
   g_free (fdata.order);
 }
 
-static void
+SWFDEC_AS_NATIVE (252, 12, swfdec_as_array_sortOn)
+void
 swfdec_as_array_sortOn (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
     SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
@@ -956,8 +1039,8 @@ swfdec_as_array_sortOn (SwfdecAsContext 
 // Constructor
 
 static void
-swfdec_as_array_construct (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
-    SwfdecAsValue *argv, SwfdecAsValue *ret)
+swfdec_as_array_construct (SwfdecAsContext *cx, SwfdecAsObject *object,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   SwfdecAsArray *array;
 
@@ -969,7 +1052,8 @@ swfdec_as_array_construct (SwfdecAsConte
     swfdec_as_object_add (object, cx, sizeof (SwfdecAsArray));
     swfdec_as_object_get_variable (cx->global, SWFDEC_AS_STR_Array, &val);
     if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) {
-      swfdec_as_object_set_constructor (object, SWFDEC_AS_VALUE_GET_OBJECT (&val), FALSE);
+      swfdec_as_object_set_constructor (object,
+	  SWFDEC_AS_VALUE_GET_OBJECT (&val), FALSE);
     } else {
       SWFDEC_INFO ("\"Array\" is not an object");
     }
@@ -994,10 +1078,10 @@ swfdec_as_array_init_context (SwfdecAsCo
 
   g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
 
-  array = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global, 
+  array = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global,
       SWFDEC_AS_STR_Array, 0, swfdec_as_array_construct, 0));
-  swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (array),
-      SWFDEC_TYPE_AS_ARRAY);
+  swfdec_as_native_function_set_construct_type (
+      SWFDEC_AS_NATIVE_FUNCTION (array), SWFDEC_TYPE_AS_ARRAY);
   if (!array)
     return;
   context->Array = array;
@@ -1005,6 +1089,7 @@ swfdec_as_array_init_context (SwfdecAsCo
     return;
   proto = g_object_new (SWFDEC_TYPE_AS_ARRAY, NULL);
   swfdec_as_object_add (proto, context, sizeof (SwfdecAsArray));
+
   /* set the right properties on the Array object */
   SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
   swfdec_as_object_set_variable (array, SWFDEC_AS_STR_prototype, &val);
@@ -1020,32 +1105,34 @@ swfdec_as_array_init_context (SwfdecAsCo
   swfdec_as_object_set_variable (array, SWFDEC_AS_STR_RETURNINDEXEDARRAY, &val);
   SWFDEC_AS_VALUE_SET_NUMBER (&val, ARRAY_SORT_OPTION_NUMERIC);
   swfdec_as_object_set_variable (array, SWFDEC_AS_STR_NUMERIC, &val);
+
   /* set the right properties on the Array.prototype object */
   SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
   swfdec_as_object_set_variable (proto, SWFDEC_AS_STR___proto__, &val);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, array);
   swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
-  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toString, 0, swfdec_as_array_toString, 0);
-  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_join, SWFDEC_TYPE_AS_ARRAY,
-      swfdec_as_array_join, 0);
-  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_push, SWFDEC_TYPE_AS_ARRAY,
-      swfdec_as_array_do_push, 0);
-  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_pop, SWFDEC_TYPE_AS_ARRAY,
-      swfdec_as_array_do_pop, 0);
-  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_unshift, SWFDEC_TYPE_AS_ARRAY,
-      swfdec_as_array_do_unshift, 0);
-  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_shift, SWFDEC_TYPE_AS_ARRAY,
-      swfdec_as_array_do_shift, 0);
-  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_reverse, SWFDEC_TYPE_AS_ARRAY,
-      swfdec_as_array_reverse, 0);
-  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_concat, SWFDEC_TYPE_AS_ARRAY,
-      swfdec_as_array_concat, 0);
-  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_slice, SWFDEC_TYPE_AS_ARRAY,
-      swfdec_as_array_slice, 0);
-  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_splice, SWFDEC_TYPE_AS_ARRAY,
-      swfdec_as_array_splice, 0);
-  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_sort, SWFDEC_TYPE_AS_ARRAY,
-      swfdec_as_array_sort, 0);
-  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_sortOn, SWFDEC_TYPE_AS_ARRAY,
-      swfdec_as_array_sortOn, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toString, 0,
+      swfdec_as_array_toString, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_join,
+      SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_join, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_push,
+      SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_do_push, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_pop,
+      SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_do_pop, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_unshift,
+      SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_do_unshift, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_shift,
+      SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_do_shift, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_reverse,
+      SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_reverse, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_concat,
+      SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_concat, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_slice,
+      SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_slice, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_splice,
+      SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_splice, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_sort,
+      SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_sort, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_sortOn,
+      SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_sortOn, 0);
 }
diff --git a/test/trace/array2-5.swf b/test/trace/array2-5.swf
index 4c11d71..4057223 100644
Binary files a/test/trace/array2-5.swf and b/test/trace/array2-5.swf differ
diff --git a/test/trace/array2-5.swf.trace b/test/trace/array2-5.swf.trace
index 38bc090..d3221d7 100644
--- a/test/trace/array2-5.swf.trace
+++ b/test/trace/array2-5.swf.trace
@@ -40,6 +40,8 @@
 [, , , , ]
 undefined
 [, , , , , , , , , ]
+[]
+[]
 [[], [], [], , ]
 []
 [[], [], [], , ]
@@ -91,9 +93,18 @@ undefined
 []
 [[], [], [], [], [], [[], [], []]]
 []
+undefined
+[[, , , , , , ]]
+[]
+undefined
+[]
+[]
 [[]]
 []
 [, , , , , []]
+[]
+[]
+[]
 [, , , , , ]
 [, , , , , , , , , , , , , ]
 []
@@ -103,6 +114,8 @@ undefined
 [, , , , , , , , , , , , , , ]
 undefined
 []
+undefined
+[]
 []
 [[], [], []]
 []
@@ -548,4 +561,27 @@ undefined
 [, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ]
 [[], [], [], [], []]
 [[[], [], []], [[], [], [], []], [], [[], []], [[]]]
+[, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ]
+[type Function]
+5
+5: a:b:c:x:z
+z
+5: a:b:c:x:
+5
+5: y:a:b:c:x
+5
+5: z:y:a:b:c
+6: z:y:a:b:c:x
+z
+6: y:a:b:c:x:x
+x,x,c,b,a,y
+6: x:x:c:b:a:y
+x:x:c:b:a:y:a:x,x,c,b,a,y
+6: x:x:c:b:a:y
+x,c
+6: x:x:c:b:a:y
+c,b,a
+5: x:x:i:j:y
+i,j,x,x,y
+5: i:j:x:x:y
 [, , , , , , ]
diff --git a/test/trace/array2-6.swf b/test/trace/array2-6.swf
index ff62b44..42059f3 100644
Binary files a/test/trace/array2-6.swf and b/test/trace/array2-6.swf differ
diff --git a/test/trace/array2-6.swf.trace b/test/trace/array2-6.swf.trace
index 84a7bd8..51dc019 100644
--- a/test/trace/array2-6.swf.trace
+++ b/test/trace/array2-6.swf.trace
@@ -40,6 +40,8 @@
 [, , , , ]
 undefined
 [, , , , , , , , , ]
+[]
+-4
 [1, b, c, , ]
 3.4
 [1, b, c, , ]
@@ -91,9 +93,18 @@ a:b:c
 6
 [1, 2, 3, 4, 5, [a, b, c]]
 1
+undefined
+[weirder]
+0
+undefined
+[]
+1
 [6]
 6
 [, , , , , 6]
+-2
+x
+-2
 ## Pop
 # Normal usage
 4
@@ -103,6 +114,8 @@ c
 # Special cases
 undefined
 []
+undefined
+[]
 4
 [1, b, c]
 c
@@ -548,4 +561,27 @@ sort customfunc 30 [[1, 2, 3], [1, 2, 3,
 sort customfunc 31 [[1, 2, 3], [1, 2, 3, 4], [], [1, 2], [1]]
 [1, 0, 3, 4, 2]
 [[1, 2, 3], [1, 2, 3, 4], [], [1, 2], [1]]
+## Fake Array (Object with Array's methods)
+[type Function]
+5
+5: a:b:c:x:z
+z
+5: a:b:c:x:
+5
+5: y:a:b:c:x
+5
+5: z:y:a:b:c
+6: z:y:a:b:c:x
+z
+6: y:a:b:c:x:x
+x,x,c,b,a,y
+6: x:x:c:b:a:y
+x:x:c:b:a:y:a:x,x,c,b,a,y
+6: x:x:c:b:a:y
+x,c
+6: x:x:c:b:a:y
+c,b,a
+5: x:x:i:j:y
+i,j,x,x,y
+5: i:j:x:x:y
 ## Done
diff --git a/test/trace/array2-7.swf b/test/trace/array2-7.swf
index db297a0..1ceb5d9 100644
Binary files a/test/trace/array2-7.swf and b/test/trace/array2-7.swf differ
diff --git a/test/trace/array2-7.swf.trace b/test/trace/array2-7.swf.trace
index 51ea2a3..04a5849 100644
--- a/test/trace/array2-7.swf.trace
+++ b/test/trace/array2-7.swf.trace
@@ -40,6 +40,8 @@
 [undefined, undefined, undefined, undefined, undefined]
 undefined
 [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]
+[]
+-4
 [1, b, c, undefined, ]
 3.4
 [1, b, c, undefined, ]
@@ -91,9 +93,18 @@ undefined:undefined:undefined:undefined:
 6
 [1, 2, 3, 4, 5, [a, b, c]]
 1
+undefined
+[weirder]
+0
+undefined
+[]
+1
 [6]
 6
 [undefined, undefined, undefined, undefined, undefined, 6]
+-2
+x
+-2
 ## Pop
 # Normal usage
 4
@@ -103,6 +114,8 @@ c
 # Special cases
 undefined
 []
+undefined
+[]
 4
 [1, b, c]
 c
@@ -548,4 +561,27 @@ sort customfunc 30 [[1, 2, 3], [1, 2, 3,
 sort customfunc 31 [[1, 2, 3], [1, 2, 3, 4], [], [1, 2], [1]]
 [1, 0, 3, 4, 2]
 [[1, 2, 3], [1, 2, 3, 4], [], [1, 2], [1]]
+## Fake Array (Object with Array's methods)
+[type Function]
+5
+5: a:b:c:x:z
+z
+5: a:b:c:x:undefined
+5
+5: y:a:b:c:x
+5
+5: z:y:a:b:c
+6: z:y:a:b:c:x
+z
+6: y:a:b:c:x:x
+x,x,c,b,a,y
+6: x:x:c:b:a:y
+x:x:c:b:a:y:a:x,x,c,b,a,y
+6: x:x:c:b:a:y
+x,c
+6: x:x:c:b:a:y
+c,b,a
+5: x:x:i:j:y
+i,j,x,x,y
+5: i:j:x:x:y
 ## Done
diff --git a/test/trace/array2.as b/test/trace/array2.as
index 7e8edb4..bea9179 100644
--- a/test/trace/array2.as
+++ b/test/trace/array2.as
@@ -96,6 +96,10 @@ mytrace (a);
 mytrace (a[9]);
 a.length = 10;
 mytrace (a);
+a = new Array (1, "b", "c", 4);		// negative value
+a.length = -4;
+mytrace (a);
+mytrace (a.length);
 a = new Array (1, "b", "c", 4);		// floating point values
 a.length = 3.4;
 mytrace (a);
@@ -187,12 +191,27 @@ mytrace (a.push ());			// pushing nothin
 mytrace (a);
 mytrace (a.push (["a", "b", "c"]));	// pushing another array
 mytrace (a);
+a = new Array ();			// pushing when weird length
+a.length = "weird";
+mytrace (a.push ("weirder"));
+mytrace (a["weird"]);
+mytrace (a);
+a = new Array ();			// pushing nothing, weird length
+a.length = "weird";
+mytrace (a.push ());
+mytrace (a["weird"]);
+mytrace (a);
 a = new Array ();			// pushing on empty array
 mytrace (a.push (6));
 mytrace (a);
 a = new Array (5);			// pushing on array with only undefined values
 mytrace (a.push (6));
 mytrace (a);
+a = new Array ();			// pushing on array with negative length
+a.length = -3;
+mytrace (a.push ("x"));
+mytrace (a[-3]);
+mytrace (a.length);
 
 
 mytrace ("## Pop");
@@ -210,6 +229,10 @@ mytrace ("# Special cases");
 a = new Array ();			// empty
 mytrace (a.pop ());
 mytrace (a);
+a = new Array ();			// empty, weird length
+a.length = "weird";
+mytrace (a.pop ());
+mytrace (a);
 a = new Array (1, "b", "c", 4);		// use parameters
 mytrace (a.pop (5));
 mytrace (a);
@@ -444,5 +467,52 @@ a = new Array ([1,2,3], [1,2,3,4], [], [
 sortall (a, compare_array_length, 0, 0);
 
 
+mytrace ("## Fake Array (Object with Array's methods)");
+
+fake = new Object();
+
+fake.join = Array.prototype.join;
+fake.toString = Array.prototype.toString;
+fake.push = Array.prototype.push;
+fake.pop = Array.prototype.pop;
+fake.shift = Array.prototype.shift;
+fake.unshift = Array.prototype.unshift;
+fake.reverse = Array.prototype.reverse;
+fake.concat = Array.prototype.concat;
+fake.slice = Array.prototype.slice;
+fake.splice = Array.prototype.splice;
+fake.sort = Array.prototype.sort;
+
+trace (fake.push);
+trace (fake.push ("a", "b", "c", "x", "z"));
+trace (fake.length + ": " + fake.join (":"));
+trace (fake.pop ());
+trace (fake.length + ": " + fake.join (":"));
+
+trace (fake.unshift ("y"));
+trace (fake.length + ": " + fake.join (":"));
+trace (fake.unshift ("z"));
+trace (fake.length + ": " + fake.join (":"));
+fake.length++;
+trace (fake.length + ": " + fake.join (":"));
+trace (fake.shift ());
+trace (fake.length + ": " + fake.join (":"));
+
+trace (fake.reverse ());
+trace (fake.length + ": " + fake.join (":"));
+
+trace (fake.concat ("a", fake).join (":"));
+trace (fake.length + ": " + fake.join (":"));
+
+trace (fake.slice (1, 3));
+trace (fake.length + ": " + fake.join (":"));
+
+trace (fake.splice (2, 3, "i", "j"));
+trace (fake.length + ": " + fake.join (":"));
+
+trace (fake.sort ());
+trace (fake.length + ": " + fake.join (":"));
+
+
 mytrace ("## Done");
 loadMovie ("FSCommand:quit", "");


More information about the Swfdec mailing list