[Swfdec] Branch 'as' - 13 commits - libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_string.c libswfdec/swfdec_as_strings.c libswfdec/swfdec_as_super.c libswfdec/swfdec_as_with.c libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_debugger.c libswfdec/swfdec_script.c libswfdec/swfdec_script.h test/trace

Benjamin Otte company at kemper.freedesktop.org
Wed Jun 6 07:37:23 PDT 2007


 libswfdec/swfdec_as_context.c               |   24 +++
 libswfdec/swfdec_as_context.h               |    2 
 libswfdec/swfdec_as_frame.c                 |   56 +++++--
 libswfdec/swfdec_as_frame.h                 |    4 
 libswfdec/swfdec_as_interpret.c             |   18 +-
 libswfdec/swfdec_as_object.c                |   85 +++-------
 libswfdec/swfdec_as_object.h                |   16 +-
 libswfdec/swfdec_as_string.c                |   58 +++++++
 libswfdec/swfdec_as_strings.c               |    2 
 libswfdec/swfdec_as_super.c                 |    3 
 libswfdec/swfdec_as_with.c                  |    8 -
 libswfdec/swfdec_bits.c                     |   59 +++++--
 libswfdec/swfdec_bits.h                     |    2 
 libswfdec/swfdec_debugger.c                 |    9 -
 libswfdec/swfdec_script.c                   |   62 ++++---
 libswfdec/swfdec_script.h                   |    7 
 test/trace/Makefile.am                      |   56 ++++++-
 test/trace/charat-5.swf                     |binary
 test/trace/charat-5.swf.trace               |  221 ++++++++++++++++++++++++++++
 test/trace/charat-6.swf                     |binary
 test/trace/charat-6.swf.trace               |  221 ++++++++++++++++++++++++++++
 test/trace/charat-7.swf                     |binary
 test/trace/charat-7.swf.trace               |  221 ++++++++++++++++++++++++++++
 test/trace/charat.as                        |   10 +
 test/trace/delete-object-5.swf              |binary
 test/trace/delete-object-5.swf.trace        |    4 
 test/trace/delete-object-6.swf              |binary
 test/trace/delete-object-6.swf.trace        |    4 
 test/trace/delete-object-7.swf              |binary
 test/trace/delete-object-7.swf.trace        |    4 
 test/trace/delete-object.as                 |   13 +
 test/trace/delete-prototypes-5.swf          |binary
 test/trace/delete-prototypes-5.swf.trace    |    4 
 test/trace/delete-prototypes-6.swf          |binary
 test/trace/delete-prototypes-6.swf.trace    |    4 
 test/trace/delete-prototypes-7.swf          |binary
 test/trace/delete-prototypes-7.swf.trace    |    4 
 test/trace/delete-prototypes.as             |   14 +
 test/trace/with-delete-5.swf                |binary
 test/trace/with-delete-5.swf.trace          |   13 +
 test/trace/with-delete-6.swf                |binary
 test/trace/with-delete-6.swf.trace          |   13 +
 test/trace/with-delete-7.swf                |binary
 test/trace/with-delete-7.swf.trace          |   13 +
 test/trace/with-delete.as                   |   24 +++
 test/trace/with-function-delete-5.swf       |binary
 test/trace/with-function-delete-5.swf.trace |   10 +
 test/trace/with-function-delete-6.swf       |binary
 test/trace/with-function-delete-6.swf.trace |   10 +
 test/trace/with-function-delete-7.swf       |binary
 test/trace/with-function-delete-7.swf.trace |   10 +
 test/trace/with-function-delete.as          |   26 +++
 test/trace/with-prototypes-5.swf            |binary
 test/trace/with-prototypes-5.swf.trace      |    3 
 test/trace/with-prototypes-6.swf            |binary
 test/trace/with-prototypes-6.swf.trace      |    3 
 test/trace/with-prototypes-7.swf            |binary
 test/trace/with-prototypes-7.swf.trace      |    3 
 test/trace/with-prototypes.as               |   14 +
 59 files changed, 1188 insertions(+), 149 deletions(-)

New commits:
diff-tree bf3f17bb8f8aa3d5a9cf4d4121e77efc2c1f048c (from 10e5b6967cb6df937b34a9d9cad410bc7c9e4d59)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 16:32:37 2007 +0200

    add test for String.charAt() and String.charCodeAt()

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 0c58f4d..79ab157 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -45,6 +45,13 @@ EXTRA_DIST = \
 	case1-6.swf.trace \
 	case1-7.swf \
 	case1-7.swf.trace \
+	charat.as \
+	charat-5.swf \
+	charat-5.swf.trace \
+	charat-6.swf \
+	charat-6.swf.trace \
+	charat-7.swf \
+	charat-7.swf.trace \
 	children.swf \
 	children.swf.trace \
 	chr.as \
diff --git a/test/trace/charat-5.swf b/test/trace/charat-5.swf
new file mode 100644
index 0000000..5146b64
Binary files /dev/null and b/test/trace/charat-5.swf differ
diff --git a/test/trace/charat-5.swf.trace b/test/trace/charat-5.swf.trace
new file mode 100644
index 0000000..288b443
--- /dev/null
+++ b/test/trace/charat-5.swf.trace
@@ -0,0 +1,221 @@
+Check charAt and CharCodeAt
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+G
+71
+r
+114
+Ã
+195
+¼
+188
+Ã
+195
+Ÿ
+159
+ 
+32
+G
+71
+o
+111
+t
+116
+t
+116
+ 
+32
+ÃŽ
+206
+“
+147
+ÃŽ
+206
+µ
+181
+ÃŽ
+206
+¹
+185
+ÃŽ
+206
+¬
+172
+ 
+32
+Ï
+207
+ƒ
+131
+ÃŽ
+206
+±
+177
+Ï
+207
+‚
+130
+ 
+32
+×
+215
+©
+169
+×
+215
+œ
+156
+×
+215
+•
+149
+×
+215
+
+157
+ 
+32
+æ
+230
+—
+151
+Â¥
+165
+æ
+230
+œ
+156
+¬
+172
+è
+232
+ª
+170
+ž
+158
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
+
+0
diff --git a/test/trace/charat-6.swf b/test/trace/charat-6.swf
new file mode 100644
index 0000000..caa5268
Binary files /dev/null and b/test/trace/charat-6.swf differ
diff --git a/test/trace/charat-6.swf.trace b/test/trace/charat-6.swf.trace
new file mode 100644
index 0000000..d59d99f
--- /dev/null
+++ b/test/trace/charat-6.swf.trace
@@ -0,0 +1,221 @@
+Check charAt and CharCodeAt
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+G
+71
+r
+114
+ü
+252
+ß
+223
+ 
+32
+G
+71
+o
+111
+t
+116
+t
+116
+ 
+32
+Γ
+915
+ε
+949
+ι
+953
+ά
+940
+ 
+32
+σ
+963
+α
+945
+Ï‚
+962
+ 
+32
+ש
+1513
+ל
+1500
+ו
+1493
+ם
+1501
+ 
+32
+æ—¥
+26085
+本
+26412
+語
+35486
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
diff --git a/test/trace/charat-7.swf b/test/trace/charat-7.swf
new file mode 100644
index 0000000..cc89ff5
Binary files /dev/null and b/test/trace/charat-7.swf differ
diff --git a/test/trace/charat-7.swf.trace b/test/trace/charat-7.swf.trace
new file mode 100644
index 0000000..d59d99f
--- /dev/null
+++ b/test/trace/charat-7.swf.trace
@@ -0,0 +1,221 @@
+Check charAt and CharCodeAt
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+G
+71
+r
+114
+ü
+252
+ß
+223
+ 
+32
+G
+71
+o
+111
+t
+116
+t
+116
+ 
+32
+Γ
+915
+ε
+949
+ι
+953
+ά
+940
+ 
+32
+σ
+963
+α
+945
+Ï‚
+962
+ 
+32
+ש
+1513
+ל
+1500
+ו
+1493
+ם
+1501
+ 
+32
+æ—¥
+26085
+本
+26412
+語
+35486
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
+
+NaN
diff --git a/test/trace/charat.as b/test/trace/charat.as
new file mode 100644
index 0000000..400372b
--- /dev/null
+++ b/test/trace/charat.as
@@ -0,0 +1,10 @@
+// makeswf -v 7 -s 200x150 -r 1 -o charat.swf charat.as
+
+trace ("Check charAt and CharCodeAt");
+s = "Grüß Gott Γειά σας שלום 日本語";
+for (i = -10; i < 100; i++) {
+  trace (s.charAt (i));
+  trace (s.charCodeAt (i));
+};
+
+loadMovie ("FSCommand:quit", "");
diff-tree 10e5b6967cb6df937b34a9d9cad410bc7c9e4d59 (from d26079526cc944606e9f3fb72cdb72faa09d0494)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 16:31:36 2007 +0200

    add test for deletes from withn a function defined in a with block

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 1154931..0c58f4d 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -400,6 +400,13 @@ EXTRA_DIST = \
 	with-delete-6.swf.trace \
 	with-delete-7.swf \
 	with-delete-7.swf.trace \
+	with-function-delete.as \
+	with-function-delete-5.swf \
+	with-function-delete-5.swf.trace \
+	with-function-delete-6.swf \
+	with-function-delete-6.swf.trace \
+	with-function-delete-7.swf \
+	with-function-delete-7.swf.trace \
 	with-prototypes.as \
 	with-prototypes-5.swf \
 	with-prototypes-5.swf.trace \
diff --git a/test/trace/with-function-delete-5.swf b/test/trace/with-function-delete-5.swf
new file mode 100644
index 0000000..2a24df6
Binary files /dev/null and b/test/trace/with-function-delete-5.swf differ
diff --git a/test/trace/with-function-delete-5.swf.trace b/test/trace/with-function-delete-5.swf.trace
new file mode 100644
index 0000000..ab252a1
--- /dev/null
+++ b/test/trace/with-function-delete-5.swf.trace
@@ -0,0 +1,10 @@
+3
+0
+4
+undefined
+5
+undefined
+6
+undefined
+7
+undefined
diff --git a/test/trace/with-function-delete-6.swf b/test/trace/with-function-delete-6.swf
new file mode 100644
index 0000000..5a1072f
Binary files /dev/null and b/test/trace/with-function-delete-6.swf differ
diff --git a/test/trace/with-function-delete-6.swf.trace b/test/trace/with-function-delete-6.swf.trace
new file mode 100644
index 0000000..873d7d8
--- /dev/null
+++ b/test/trace/with-function-delete-6.swf.trace
@@ -0,0 +1,10 @@
+3
+2
+4
+1
+5
+0
+6
+-1
+7
+undefined
diff --git a/test/trace/with-function-delete-7.swf b/test/trace/with-function-delete-7.swf
new file mode 100644
index 0000000..a1255aa
Binary files /dev/null and b/test/trace/with-function-delete-7.swf differ
diff --git a/test/trace/with-function-delete-7.swf.trace b/test/trace/with-function-delete-7.swf.trace
new file mode 100644
index 0000000..873d7d8
--- /dev/null
+++ b/test/trace/with-function-delete-7.swf.trace
@@ -0,0 +1,10 @@
+3
+2
+4
+1
+5
+0
+6
+-1
+7
+undefined
diff --git a/test/trace/with-function-delete.as b/test/trace/with-function-delete.as
new file mode 100644
index 0000000..3bc559a
--- /dev/null
+++ b/test/trace/with-function-delete.as
@@ -0,0 +1,26 @@
+// makeswf -v 7 -s 200x150 -r 1 -o with-function-delete.swf with-function-delete.as
+
+trace ("Check how delete works inside functions defined in a With statement");
+
+x = 0;
+_global.x = -1;
+o = { x: 1 };
+p = { x: 2 };
+with (o) {
+  with (p) {
+    foo = function (x) {
+      trace (x);
+      delete x;
+      trace (x);
+      delete x;
+    };
+  };
+};
+
+foo (3);
+foo (4);
+foo (5);
+foo (6);
+foo (7);
+
+loadMovie ("FSCommand:quit", "");
diff-tree d26079526cc944606e9f3fb72cdb72faa09d0494 (from ad83487f995f4c10dbed77adfbb8e94a42a08c98)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 16:30:02 2007 +0200

    handle reading strings better
    
    Strings are LATIN1 in Flash <= 5 and only became UTF8 in Flash 6.
    swfdec_bits_skip_string () has been removed because of this and
    swfdec_bits_get_string_with_version() that automatically does the right
    conversion.
    
    swfdec_bits_get_string() should be considered deprecated. Someone should add
    some tests to ensure all strings behave like this and switch the rest of the
    functions.

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index e0f6fe2..0c312bf 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -130,7 +130,7 @@ swfdec_as_frame_new (SwfdecAsContext *co
   if (script->constant_pool) {
     frame->constant_pool_buffer = swfdec_buffer_ref (script->constant_pool);
     frame->constant_pool = swfdec_constant_pool_new_from_action (
-	script->constant_pool->data, script->constant_pool->length);
+	script->constant_pool->data, script->constant_pool->length, script->version);
     if (frame->constant_pool) {
       swfdec_constant_pool_attach_to_context (frame->constant_pool, context);
     } else {
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 7c3fcbc..d1e4b57 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -319,7 +319,7 @@ swfdec_action_constant_pool (SwfdecAsCon
   SwfdecAsFrame *frame;
 
   frame = cx->frame;
-  pool = swfdec_constant_pool_new_from_action (data, len);
+  pool = swfdec_constant_pool_new_from_action (data, len, cx->version);
   if (pool == NULL)
     return;
   swfdec_constant_pool_attach_to_context (pool, cx);
@@ -346,7 +346,7 @@ swfdec_action_push (SwfdecAsContext *cx,
     switch (type) {
       case 0: /* string */
 	{
-	  const char *s = swfdec_bits_skip_string (&bits);
+	  char *s = swfdec_bits_get_string_with_version (&bits, cx->version);
 	  if (s == NULL)
 	    return;
 	  SWFDEC_AS_VALUE_SET_STRING (swfdec_as_stack_push (stack), 
@@ -1433,7 +1433,7 @@ swfdec_action_define_function (SwfdecAsC
 
   frame = cx->frame;
   swfdec_bits_init_data (&bits, data, len);
-  function_name = swfdec_bits_skip_string (&bits);
+  function_name = swfdec_bits_get_string_with_version (&bits, cx->version);
   if (function_name == NULL) {
     SWFDEC_ERROR ("could not parse function name");
     return;
@@ -2120,7 +2120,8 @@ swfdec_action_print_push (guint action, 
     switch (type) {
       case 0: /* string */
 	{
-	  const char *s = swfdec_bits_skip_string (&bits);
+	  /* FIXME: need version! */
+	  char *s = swfdec_bits_get_string (&bits);
 	  if (!s) {
 	    g_string_free (string, TRUE);
 	    return NULL;
@@ -2128,6 +2129,7 @@ swfdec_action_print_push (guint action, 
 	  g_string_append_c (string, '"');
 	  g_string_append (string, s);
 	  g_string_append_c (string, '"');
+	  g_free (s);
 	  break;
 	}
       case 1: /* float */
@@ -2173,7 +2175,8 @@ swfdec_action_print_constant_pool (guint
   GString *string;
   SwfdecConstantPool *pool;
 
-  pool = swfdec_constant_pool_new_from_action (data, len);
+  /* FIXME: version */
+  pool = swfdec_constant_pool_new_from_action (data, len, 6);
   if (pool == NULL)
     return g_strdup ("ConstantPool (invalid)");
   string = g_string_new ("ConstantPool");
diff --git a/libswfdec/swfdec_as_strings.c b/libswfdec/swfdec_as_strings.c
index 7f085cc..8b24f37 100644
--- a/libswfdec/swfdec_as_strings.c
+++ b/libswfdec/swfdec_as_strings.c
@@ -204,6 +204,8 @@ const char swfdec_as_strings[] = 
   SWFDEC_AS_CONSTANT_STRING ("clearInterval")
   SWFDEC_AS_CONSTANT_STRING ("escape")
   SWFDEC_AS_CONSTANT_STRING ("unescape")
+  SWFDEC_AS_CONSTANT_STRING ("charAt")
+  SWFDEC_AS_CONSTANT_STRING ("charCodeAt")
   /* add more here */
 ;
 
diff --git a/libswfdec/swfdec_bits.c b/libswfdec/swfdec_bits.c
index c8a5062..9fb0041 100644
--- a/libswfdec/swfdec_bits.c
+++ b/libswfdec/swfdec_bits.c
@@ -470,22 +470,14 @@ swfdec_bits_get_matrix (SwfdecBits * bit
   swfdec_bits_syncbits (bits);
 }
 
-char *
-swfdec_bits_get_string (SwfdecBits * bits)
-{
-  const char *s = swfdec_bits_skip_string (bits);
-
-  return g_strdup (s);
-}
-
-const char *
+static const char *
 swfdec_bits_skip_string (SwfdecBits *bits)
 {
   char *s;
   const char *end;
   guint len;
 
-  swfdec_bits_syncbits (bits);
+  SWFDEC_BYTES_CHECK (bits, 1);
   end = memchr (bits->ptr, 0, bits->end - bits->ptr);
   if (end == NULL) {
     SWFDEC_ERROR ("could not parse string");
@@ -495,15 +487,54 @@ swfdec_bits_skip_string (SwfdecBits *bit
   len = end - (const char *) bits->ptr;
   s = (char *) bits->ptr;
   bits->ptr += len + 1;
-  if (!g_utf8_validate (s, -1, NULL)) {
-    SWFDEC_ERROR ("parsed string is not valid utf-8");
-    s = NULL;
-  }
 
   return s;
 }
 
 /**
+ * swfdec_bits_get_string_with_version:
+ * @bits: a #SwfdecBits
+ * @version: Flash player version
+ *
+ * Prior to Flash 6, strings used to be encoded as LATIN1. Since Flash 6, 
+ * strings are encoded as UTF8. This version does the check automatically
+ * and converts strings to UTF-8.
+ *
+ * Returns: a UTF-8 encoded string or %NULL on error
+ **/
+char *
+swfdec_bits_get_string_with_version (SwfdecBits *bits, guint version)
+{
+  const char *s;
+  
+  g_return_val_if_fail (bits != NULL, NULL);
+
+  s = swfdec_bits_skip_string (bits);
+  if (s == NULL)
+    return NULL;
+
+  if (version < 6) {
+    char *ret = g_convert (s, -1, "UTF8", "LATIN1", NULL , NULL, NULL);
+    if (ret == NULL)
+      g_warning ("Could not convert string from LATIN1 to UTF8");
+    return ret;
+  } else {
+    if (!g_utf8_validate (s, -1, NULL)) {
+      SWFDEC_ERROR ("parsed string is not valid utf-8");
+      return NULL;
+    }
+    return g_strdup (s);
+  }
+}
+
+/* FIXME: deprecated - someone remove this */
+char *
+swfdec_bits_get_string (SwfdecBits * bits)
+{
+  return swfdec_bits_get_string_with_version (bits, 6);
+}
+
+/**
  * swfdec_bits_skip_bytes:
  * @bits: a #SwfdecBits
  * @n_bytes: number of bytes to skip
diff --git a/libswfdec/swfdec_bits.h b/libswfdec/swfdec_bits.h
index a86e705..8d6492e 100644
--- a/libswfdec/swfdec_bits.h
+++ b/libswfdec/swfdec_bits.h
@@ -61,10 +61,10 @@ void swfdec_bits_get_color_transform (Sw
     SwfdecColorTransform * ct);
 void swfdec_bits_get_matrix (SwfdecBits * bits, cairo_matrix_t *matrix, 
     cairo_matrix_t *inverse);
-const char *swfdec_bits_skip_string (SwfdecBits * bits);
 guint swfdec_bits_skip_bytes (SwfdecBits *bits, guint bytes);
 char *swfdec_bits_get_string (SwfdecBits * bits);
 char *swfdec_bits_get_string_length (SwfdecBits * bits, guint len);
+char *swfdec_bits_get_string_with_version (SwfdecBits *bits, guint version);
 SwfdecColor swfdec_bits_get_color (SwfdecBits * bits);
 SwfdecColor swfdec_bits_get_rgba (SwfdecBits * bits);
 SwfdecGradient *swfdec_bits_get_gradient (SwfdecBits * bits);
diff --git a/libswfdec/swfdec_debugger.c b/libswfdec/swfdec_debugger.c
index 8d0a96e..52ae539 100644
--- a/libswfdec/swfdec_debugger.c
+++ b/libswfdec/swfdec_debugger.c
@@ -47,6 +47,7 @@ static guint signals[LAST_SIGNAL] = { 0,
 /*** SwfdecDebuggerScript ***/
 
 typedef struct {
+  guint			version;	/* version of parsed file */
   SwfdecConstantPool *	constant_pool;	/* current constant pool */
   GArray *		commands;	/* SwfdecDebuggerCommands parsed so far */
 } ScriptParser;
@@ -69,12 +70,13 @@ swfdec_debugger_print_push (ScriptParser
     switch (type) {
       case 0: /* string */
 	{
-	  const char *s = swfdec_bits_skip_string (&bits);
+	  char *s = swfdec_bits_get_string_with_version (&bits, parser->version);
 	  if (!s)
 	    goto error;
 	  g_string_append_c (string, '"');
 	  g_string_append (string, s);
 	  g_string_append_c (string, '"');
+	  g_free (s);
 	  break;
 	}
       case 1: /* float */
@@ -150,7 +152,7 @@ swfdec_debugger_add_command (gconstpoint
   if (action == SWFDEC_AS_ACTION_CONSTANT_POOL) {
     if (parser->constant_pool)
       swfdec_constant_pool_free (parser->constant_pool);
-    parser->constant_pool = swfdec_constant_pool_new_from_action (data, len);
+    parser->constant_pool = swfdec_constant_pool_new_from_action (data, len, parser->version);
   }
   return TRUE;
 }
@@ -165,9 +167,10 @@ swfdec_debugger_script_new (SwfdecScript
   ret->script = script;
   swfdec_script_ref (script);
   parser.commands = g_array_new (TRUE, FALSE, sizeof (SwfdecDebuggerCommand));
+  parser.version = script->version;
   if (script->constant_pool) {
     parser.constant_pool = swfdec_constant_pool_new_from_action (
-	script->constant_pool->data, script->constant_pool->length);
+	script->constant_pool->data, script->constant_pool->length, parser.version);
   } else {
     parser.constant_pool = NULL;
   }
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index bc1b964..bf38d51 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -44,36 +44,37 @@
 
 /*** CONSTANT POOLS ***/
 
+struct _SwfdecConstantPool {
+  SwfdecAsContext *	context;	/* context we are attached to or NULL */
+  guint			n_strings;	/* number of strings */
+  char *		strings[1];	/* n_strings strings */
+};
+
 SwfdecConstantPool *
-swfdec_constant_pool_new_from_action (const guint8 *data, guint len)
+swfdec_constant_pool_new_from_action (const guint8 *data, guint len, guint version)
 {
-  guint8 *next;
   guint i, n;
-  GPtrArray *pool;
+  SwfdecBits bits;
+  SwfdecConstantPool *pool;
 
-  if (len < 2) {
-    SWFDEC_ERROR ("constant pool too small");
+  swfdec_bits_init_data (&bits, data, len);
+
+  n = swfdec_bits_get_u16 (&bits);
+  if (n == 0)
     return NULL;
-  }
-  n = GUINT16_FROM_LE (*((guint16*) data));
-  data += 2;
-  len -= 2;
-  pool = g_ptr_array_sized_new (n);
-  g_ptr_array_set_size (pool, n);
+
+  pool = g_malloc0 (sizeof (SwfdecConstantPool) + (n - 1) * sizeof (char *));
+  pool->n_strings = n;
   for (i = 0; i < n; i++) {
-    next = memchr (data, 0, len);
-    if (next == NULL) {
+    pool->strings[i] = swfdec_bits_get_string_with_version (&bits, version);
+    if (pool->strings[i] == NULL) {
       SWFDEC_ERROR ("not enough strings available");
-      g_ptr_array_free (pool, TRUE);
+      swfdec_constant_pool_free (pool);
       return NULL;
     }
-    next++;
-    g_ptr_array_index (pool, i) = (gpointer) data;
-    len -= next - data;
-    data = next;
   }
-  if (len != 0) {
-    SWFDEC_WARNING ("constant pool didn't consume whole buffer (%u bytes leftover)", len);
+  if (swfdec_bits_left (&bits)) {
+    SWFDEC_WARNING ("constant pool didn't consume whole buffer (%u bytes leftover)", swfdec_bits_left (&bits) / 8);
   }
   return pool;
 }
@@ -84,31 +85,38 @@ swfdec_constant_pool_attach_to_context (
   guint i;
 
   g_return_if_fail (pool != NULL);
+  g_return_if_fail (pool->context == NULL);
   g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
 
-  for (i = 0; i < pool->len; i++) {
-    g_ptr_array_index (pool, i) = (gpointer) swfdec_as_context_get_string (context, 
-	g_ptr_array_index (pool, i));
+  pool->context = context;
+  for (i = 0; i < pool->n_strings; i++) {
+    pool->strings[i] = (char *) swfdec_as_context_give_string (context, pool->strings[i]);
   }
 }
 
 guint
 swfdec_constant_pool_size (SwfdecConstantPool *pool)
 {
-  return pool->len;
+  return pool->n_strings;
 }
 
 const char *
 swfdec_constant_pool_get (SwfdecConstantPool *pool, guint i)
 {
-  g_assert (i < pool->len);
-  return g_ptr_array_index (pool, i);
+  g_assert (i < pool->n_strings);
+  return pool->strings[i];
 }
 
 void
 swfdec_constant_pool_free (SwfdecConstantPool *pool)
 {
-  g_ptr_array_free (pool, TRUE);
+  if (pool->context == NULL) {
+    guint i;
+    for (i = 0; i < pool->n_strings; i++) {
+      g_free (pool->strings[i]);
+    }
+  }
+  g_free (pool);
 }
 
 /*** SUPPORT FUNCTIONS ***/
diff --git a/libswfdec/swfdec_script.h b/libswfdec/swfdec_script.h
index 643001f..267aecb 100644
--- a/libswfdec/swfdec_script.h
+++ b/libswfdec/swfdec_script.h
@@ -29,7 +29,7 @@ G_BEGIN_DECLS
 
 //typedef struct _SwfdecScript SwfdecScript;
 typedef struct _SwfdecScriptArgument SwfdecScriptArgument;
-typedef GPtrArray SwfdecConstantPool;
+typedef struct _SwfdecConstantPool SwfdecConstantPool;
 
 typedef enum {
   SWFDEC_SCRIPT_PRELOAD_THIS = (1 << 0),
@@ -71,8 +71,9 @@ const char *	swfdec_action_get_name		(gu
 guint		swfdec_action_get_from_name	(const char *		name);
 
 SwfdecConstantPool *
-		swfdec_constant_pool_new_from_action	(const guint8 *	data,
-							 guint			len);
+		swfdec_constant_pool_new_from_action	(const guint8 *		data,
+							 guint			len,
+							 guint			version);
 void		swfdec_constant_pool_free	  	(SwfdecConstantPool *	pool);
 guint		swfdec_constant_pool_size		(SwfdecConstantPool *	pool);
 const char *	swfdec_constant_pool_get		(SwfdecConstantPool *	pool,
diff-tree ad83487f995f4c10dbed77adfbb8e94a42a08c98 (from c679eed66607c228a12788da17236dd6b4d0e168)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 16:27:13 2007 +0200

    implement String.charAt() and String.charCodeAt()

diff --git a/libswfdec/swfdec_as_string.c b/libswfdec/swfdec_as_string.c
index cdf6fbd..d18b068 100644
--- a/libswfdec/swfdec_as_string.c
+++ b/libswfdec/swfdec_as_string.c
@@ -57,6 +57,62 @@ swfdec_as_string_init (SwfdecAsString *s
 
 /*** AS CODE ***/
 
+static inline const char *
+swfdec_as_str_nth_char (const char *s, guint n)
+{
+  while (*s && n--)
+    s = g_utf8_next_char (s);
+  return s;
+}
+
+static void
+swfdec_as_string_charAt (SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+{
+  SwfdecAsString *string = SWFDEC_AS_STRING (object);
+  int i;
+  const char *s, *t;
+
+  i = swfdec_as_value_to_integer (object->context, &argv[0]);
+  if (i < 0) {
+    SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_AS_STR_EMPTY);
+    return;
+  }
+  s = swfdec_as_str_nth_char (string->string, i);
+  if (*s == 0) {
+    SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_AS_STR_EMPTY);
+    return;
+  }
+  t = g_utf8_next_char (s);
+  s = swfdec_as_context_give_string (object->context, g_strndup (s, t - s));
+  SWFDEC_AS_VALUE_SET_STRING (ret, s);
+}
+
+static void
+swfdec_as_string_charCodeAt (SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+{
+  SwfdecAsString *string = SWFDEC_AS_STRING (object);
+  int i;
+  const char *s;
+  gunichar c;
+
+  i = swfdec_as_value_to_integer (object->context, &argv[0]);
+  if (i < 0) {
+    SWFDEC_AS_VALUE_SET_NUMBER (ret, NAN);
+    return;
+  }
+  s = swfdec_as_str_nth_char (string->string, i);
+  if (*s == 0) {
+    if (object->context->version > 5) {
+      SWFDEC_AS_VALUE_SET_NUMBER (ret, NAN);
+    } else {
+      SWFDEC_AS_VALUE_SET_INT (ret, 0);
+    }
+    return;
+  }
+  c = g_utf8_get_char (s);
+  SWFDEC_AS_VALUE_SET_NUMBER (ret, c);
+}
+
 static void
 swfdec_as_string_fromCharCode_5 (SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
@@ -492,6 +548,8 @@ swfdec_as_string_init_context (SwfdecAsC
   swfdec_as_object_set_variable (proto, SWFDEC_AS_STR___proto__, &val);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, string);
   swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_charAt, SWFDEC_TYPE_AS_STRING, swfdec_as_string_charAt, 1);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_charCodeAt, SWFDEC_TYPE_AS_STRING, swfdec_as_string_charCodeAt, 1);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_substr, SWFDEC_TYPE_AS_STRING, swfdec_as_string_substr, 1);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_substring, SWFDEC_TYPE_AS_STRING, swfdec_as_string_substring, 1);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toLowerCase, SWFDEC_TYPE_AS_STRING, swfdec_as_string_toLowerCase, 0);
diff-tree c679eed66607c228a12788da17236dd6b4d0e168 (from f66b838c176e6a90a0d70df451aaa0db1dfc081f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 16:26:41 2007 +0200

    add swfdec_as_context_give_string that g_free's the given string

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index c10a5ea..50cff5b 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -356,6 +356,30 @@ swfdec_as_context_get_string (SwfdecAsCo
   return swfdec_as_context_create_string (context, string, len);
 }
 
+/**
+ * swfdec_as_context_give_string:
+ * @context: a #SwfdecAsContext
+ * @string: string to make refcounted
+ *
+ * Takes ownership of @string and returns a refcounted version of the same 
+ * string. This function is the same as swfdec_as_context_get_string(), but 
+ * takes ownership of @string.
+ *
+ * Returns: A refcounted string
+ **/
+const char *
+swfdec_as_context_give_string (SwfdecAsContext *context, char *string)
+{
+  const char *ret;
+
+  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
+  g_return_val_if_fail (string != NULL, NULL);
+
+  ret = swfdec_as_context_get_string (context, string);
+  g_free (string);
+  return ret;
+}
+
 SwfdecAsContext *
 swfdec_as_context_new (void)
 {
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index 88c6c6f..5d2d7ba 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -93,6 +93,8 @@ void		swfdec_as_context_get_time	(Swfdec
 						 GTimeVal *		tv);
 const char *	swfdec_as_context_get_string	(SwfdecAsContext *	context,
 						 const char *		string);
+const char *	swfdec_as_context_give_string	(SwfdecAsContext *	context,
+						 char *			string);
 
 #define swfdec_as_context_abort_oom(context) swfdec_as_context_abort (context, "Out of memory")
 void		swfdec_as_context_abort		(SwfdecAsContext *	context,
diff-tree f66b838c176e6a90a0d70df451aaa0db1dfc081f (from dcfd952c19e73011ef91dd111ba944409121a82a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 12:06:57 2007 +0200

    add tests for Delete behaviour

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index a9def0e..1154931 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -86,6 +86,20 @@ EXTRA_DIST = \
 	countdown.swf.trace \
 	currentframe.swf \
 	currentframe.swf.trace \
+	delete-object.as \
+	delete-object-5.swf \
+	delete-object-5.swf.trace \
+	delete-object-6.swf \
+	delete-object-6.swf.trace \
+	delete-object-7.swf \
+	delete-object-7.swf.trace \
+	delete-prototypes.as \
+	delete-prototypes-5.swf \
+	delete-prototypes-5.swf.trace \
+	delete-prototypes-6.swf \
+	delete-prototypes-6.swf.trace \
+	delete-prototypes-7.swf \
+	delete-prototypes-7.swf.trace \
 	divide.as \
 	divide-7.swf \
 	divide-7.swf.trace \
@@ -379,6 +393,13 @@ EXTRA_DIST = \
 	unescape2-7.swf \
 	unescape2-7.swf.trace \
 	video.flv \
+	with-delete.as \
+	with-delete-5.swf \
+	with-delete-5.swf.trace \
+	with-delete-6.swf \
+	with-delete-6.swf.trace \
+	with-delete-7.swf \
+	with-delete-7.swf.trace \
 	with-prototypes.as \
 	with-prototypes-5.swf \
 	with-prototypes-5.swf.trace \
diff --git a/test/trace/delete-object-5.swf b/test/trace/delete-object-5.swf
new file mode 100644
index 0000000..781abc6
Binary files /dev/null and b/test/trace/delete-object-5.swf differ
diff --git a/test/trace/delete-object-5.swf.trace b/test/trace/delete-object-5.swf.trace
new file mode 100644
index 0000000..5d7d7f3
--- /dev/null
+++ b/test/trace/delete-object-5.swf.trace
@@ -0,0 +1,4 @@
+Check that deleting from an object does not delete from the prototype
+1
+2
+2
diff --git a/test/trace/delete-object-6.swf b/test/trace/delete-object-6.swf
new file mode 100644
index 0000000..e5e2762
Binary files /dev/null and b/test/trace/delete-object-6.swf differ
diff --git a/test/trace/delete-object-6.swf.trace b/test/trace/delete-object-6.swf.trace
new file mode 100644
index 0000000..5d7d7f3
--- /dev/null
+++ b/test/trace/delete-object-6.swf.trace
@@ -0,0 +1,4 @@
+Check that deleting from an object does not delete from the prototype
+1
+2
+2
diff --git a/test/trace/delete-object-7.swf b/test/trace/delete-object-7.swf
new file mode 100644
index 0000000..371f619
Binary files /dev/null and b/test/trace/delete-object-7.swf differ
diff --git a/test/trace/delete-object-7.swf.trace b/test/trace/delete-object-7.swf.trace
new file mode 100644
index 0000000..5d7d7f3
--- /dev/null
+++ b/test/trace/delete-object-7.swf.trace
@@ -0,0 +1,4 @@
+Check that deleting from an object does not delete from the prototype
+1
+2
+2
diff --git a/test/trace/delete-object.as b/test/trace/delete-object.as
new file mode 100644
index 0000000..267a95e
--- /dev/null
+++ b/test/trace/delete-object.as
@@ -0,0 +1,13 @@
+// makeswf -v 7 -s 200x150 -r 1 -o delete-object.swf delete-object.as
+
+trace ("Check that deleting from an object does not delete from the prototype");
+
+o = { x: 1 };
+o.__proto__ = { x: 2 };
+trace (o.x);
+delete o.x;
+trace (o.x);
+delete o.x;
+trace (o.x);
+
+loadMovie ("FSCommand:quit", "");
diff --git a/test/trace/delete-prototypes-5.swf b/test/trace/delete-prototypes-5.swf
new file mode 100644
index 0000000..f51c30b
Binary files /dev/null and b/test/trace/delete-prototypes-5.swf differ
diff --git a/test/trace/delete-prototypes-5.swf.trace b/test/trace/delete-prototypes-5.swf.trace
new file mode 100644
index 0000000..f0be7d2
--- /dev/null
+++ b/test/trace/delete-prototypes-5.swf.trace
@@ -0,0 +1,4 @@
+Check that delete doesn't delete from prototypes.
+this
+prototype
+prototype
diff --git a/test/trace/delete-prototypes-6.swf b/test/trace/delete-prototypes-6.swf
new file mode 100644
index 0000000..2cbfcf5
Binary files /dev/null and b/test/trace/delete-prototypes-6.swf differ
diff --git a/test/trace/delete-prototypes-6.swf.trace b/test/trace/delete-prototypes-6.swf.trace
new file mode 100644
index 0000000..f0be7d2
--- /dev/null
+++ b/test/trace/delete-prototypes-6.swf.trace
@@ -0,0 +1,4 @@
+Check that delete doesn't delete from prototypes.
+this
+prototype
+prototype
diff --git a/test/trace/delete-prototypes-7.swf b/test/trace/delete-prototypes-7.swf
new file mode 100644
index 0000000..bc9af16
Binary files /dev/null and b/test/trace/delete-prototypes-7.swf differ
diff --git a/test/trace/delete-prototypes-7.swf.trace b/test/trace/delete-prototypes-7.swf.trace
new file mode 100644
index 0000000..f0be7d2
--- /dev/null
+++ b/test/trace/delete-prototypes-7.swf.trace
@@ -0,0 +1,4 @@
+Check that delete doesn't delete from prototypes.
+this
+prototype
+prototype
diff --git a/test/trace/delete-prototypes.as b/test/trace/delete-prototypes.as
new file mode 100644
index 0000000..7463ea0
--- /dev/null
+++ b/test/trace/delete-prototypes.as
@@ -0,0 +1,14 @@
+// makeswf -v 7 -s 200x150 -r 1 -o delete-prototypes.swf delete-prototypes.as
+
+trace ("Check that delete doesn't delete from prototypes.");
+
+x = "this";
+this.__proto__.x = "prototype";
+
+trace (x);
+delete x;
+trace (x);
+delete x;
+trace (x);
+
+loadMovie ("FSCommand:quit", "");
diff --git a/test/trace/with-delete-5.swf b/test/trace/with-delete-5.swf
new file mode 100644
index 0000000..8acc082
Binary files /dev/null and b/test/trace/with-delete-5.swf differ
diff --git a/test/trace/with-delete-5.swf.trace b/test/trace/with-delete-5.swf.trace
new file mode 100644
index 0000000..80bceb6
--- /dev/null
+++ b/test/trace/with-delete-5.swf.trace
@@ -0,0 +1,13 @@
+Check that delete inside a With doesn't delete from prototypes.
+1
+0
+1
+2
+2
+0
+2
+2
+2
+undefined
+2
+2
diff --git a/test/trace/with-delete-6.swf b/test/trace/with-delete-6.swf
new file mode 100644
index 0000000..2a7bfb8
Binary files /dev/null and b/test/trace/with-delete-6.swf differ
diff --git a/test/trace/with-delete-6.swf.trace b/test/trace/with-delete-6.swf.trace
new file mode 100644
index 0000000..80bceb6
--- /dev/null
+++ b/test/trace/with-delete-6.swf.trace
@@ -0,0 +1,13 @@
+Check that delete inside a With doesn't delete from prototypes.
+1
+0
+1
+2
+2
+0
+2
+2
+2
+undefined
+2
+2
diff --git a/test/trace/with-delete-7.swf b/test/trace/with-delete-7.swf
new file mode 100644
index 0000000..2c217b2
Binary files /dev/null and b/test/trace/with-delete-7.swf differ
diff --git a/test/trace/with-delete-7.swf.trace b/test/trace/with-delete-7.swf.trace
new file mode 100644
index 0000000..80bceb6
--- /dev/null
+++ b/test/trace/with-delete-7.swf.trace
@@ -0,0 +1,13 @@
+Check that delete inside a With doesn't delete from prototypes.
+1
+0
+1
+2
+2
+0
+2
+2
+2
+undefined
+2
+2
diff --git a/test/trace/with-delete.as b/test/trace/with-delete.as
new file mode 100644
index 0000000..4ddd663
--- /dev/null
+++ b/test/trace/with-delete.as
@@ -0,0 +1,24 @@
+// makeswf -v 7 -s 200x150 -r 1 -o with-delete.swf with-delete.as
+
+trace ("Check that delete inside a With doesn't delete from prototypes.");
+x = 0;
+o = { x: 1 };
+o.__proto__ = { x: 2 };
+with (o) {
+  trace (x);
+  trace (this.x);
+  trace (o.x);
+  trace (o.__proto__.x);
+  delete x;
+  trace (x);
+  trace (this.x);
+  trace (o.x);
+  trace (o.__proto__.x);
+  delete x;
+  trace (x);
+  trace (this.x);
+  trace (o.x);
+  trace (o.__proto__.x);
+};
+
+loadMovie ("FSCommand:quit", "");
diff-tree dcfd952c19e73011ef91dd111ba944409121a82a (from 56c6cb1ab174836cf75253e228f9b1ccff0a7c21)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 11:57:43 2007 +0200

    restore alphabetic ordering

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index d85db0f..a9def0e 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -180,6 +180,13 @@ EXTRA_DIST = \
 	height3.swf.trace \
 	height4.swf \
 	height4.swf.trace \
+	if.as \
+	if-5.swf \
+	if-5.swf.trace \
+	if-6.swf \
+	if-6.swf.trace \
+	if-7.swf \
+	if-7.swf.trace \
 	initobject-stack.as \
 	initobject-stack-5.swf \
 	initobject-stack-5.swf.trace \
@@ -194,13 +201,6 @@ EXTRA_DIST = \
 	isnan-6.swf.trace \
 	isnan-7.swf \
 	isnan-7.swf.trace \
-	if.as \
-	if-5.swf \
-	if-5.swf.trace \
-	if-6.swf \
-	if-6.swf.trace \
-	if-7.swf \
-	if-7.swf.trace \
 	jump-into-with.as \
 	jump-into-with.swf \
 	jump-into-with.swf.trace \
diff-tree 56c6cb1ab174836cf75253e228f9b1ccff0a7c21 (from 092b1c745bb08393fb2ea512cfba6fb0df6ae81d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 11:53:29 2007 +0200

    recode delete handling
    
    Delete does not delete from prototypes.

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index de0dbd7..e0f6fe2 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -232,6 +232,43 @@ swfdec_as_frame_find_variable (SwfdecAsF
   return NULL;
 }
 
+/* FIXME: merge with find_variable somehow */
+gboolean
+swfdec_as_frame_delete_variable (SwfdecAsFrame *frame, const char *variable)
+{
+  SwfdecAsScope *cur;
+  guint i;
+
+  g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), FALSE);
+  g_return_val_if_fail (variable != NULL, FALSE);
+
+  cur = frame->scope;
+  for (i = 0; i < 256; i++) {
+    if (swfdec_as_object_delete_variable (SWFDEC_AS_OBJECT (cur), variable))
+      return TRUE;
+    if (cur->next == NULL)
+      break;
+    cur = cur->next;
+  }
+  if (i == 256) {
+    swfdec_as_context_abort (SWFDEC_AS_OBJECT (frame)->context, "Scope recursion limit exceeded");
+    return FALSE;
+  }
+  g_assert (SWFDEC_IS_AS_FRAME (cur));
+  /* we've walked the scope chain down. Now look in the special objects. */
+  /* 1) the target set via SetTarget */
+  if (frame->target) {
+    if (swfdec_as_object_delete_variable (frame->target, variable))
+      return TRUE;
+  } else {
+    /* The default target is the original object that called into us */
+    if (swfdec_as_object_delete_variable (SWFDEC_AS_FRAME (cur)->thisp, variable))
+      return TRUE;
+  }
+  /* 2) the global object */
+  return swfdec_as_object_delete_variable (SWFDEC_AS_OBJECT (frame)->context->global, variable);
+}
+
 /**
  * swfdec_as_frame_set_target:
  * @frame: a #SwfdecAsFrame
diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h
index 7bb41b4..a790e47 100644
--- a/libswfdec/swfdec_as_frame.h
+++ b/libswfdec/swfdec_as_frame.h
@@ -76,6 +76,8 @@ void		swfdec_as_frame_preload		(SwfdecAs
 
 SwfdecAsObject *swfdec_as_frame_find_variable	(SwfdecAsFrame *	frame,
 						 const char *		variable);
+gboolean	swfdec_as_frame_delete_variable	(SwfdecAsFrame *	frame,
+						 const char *		variable);
 
 void		swfdec_as_frame_set_target	(SwfdecAsFrame *	frame,
 						 SwfdecAsObject *	target);
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index f1898a1..7c3fcbc 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1660,12 +1660,9 @@ static void
 swfdec_action_delete2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
   const char *name;
-  SwfdecAsObject *object;
   
   name = swfdec_as_value_to_string (cx, swfdec_as_stack_pop (cx->frame->stack));
-  object = swfdec_as_frame_find_variable (cx->frame, name);
-  if (object)
-    swfdec_as_object_delete_variable (object, name);
+  swfdec_as_frame_delete_variable (cx->frame, name);
 }
 
 static void
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 567ff16..ce48065 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -142,17 +142,22 @@ swfdec_as_object_free_property (gpointer
   g_slice_free (SwfdecAsVariable, value);
 }
 
-static void
+static gboolean
 swfdec_as_object_do_delete (SwfdecAsObject *object, const char *variable)
 {
   SwfdecAsVariable *var;
 
   var = g_hash_table_lookup (object->properties, variable);
-  g_assert (var);
+  if (var == NULL)
+    return FALSE;
+  if (var->flags & SWFDEC_AS_VARIABLE_PERMANENT)
+    return TRUE;
+
   swfdec_as_object_free_property (NULL, var, object);
   if (!g_hash_table_remove (object->properties, variable)) {
     g_assert_not_reached ();
   }
+  return TRUE;
 }
 
 typedef struct {
@@ -314,35 +319,27 @@ swfdec_as_object_set_variable (SwfdecAsO
   klass->set (object, variable, value);
 }
 
-static inline gboolean
-swfdec_as_object_lookup (SwfdecAsObject *object, const char *variable, 
-    SwfdecAsValue *value, guint *flags)
-{
-  SwfdecAsObjectClass *klass;
-  SwfdecAsValue tmp_val;
-  guint tmp_flags;
-
-  if (value == NULL)
-    value = &tmp_val;
-  if (flags == NULL)
-    flags = &tmp_flags;
-
-  klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
-  return klass->get (object, variable, value, flags);
-}
-
 gboolean
 swfdec_as_object_get_variable_and_flags (SwfdecAsObject *object, 
     const char *variable, SwfdecAsValue *value, guint *flags)
 {
+  SwfdecAsObjectClass *klass;
   guint i;
+  SwfdecAsValue tmp_val;
+  guint tmp_flags;
 
   g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), FALSE);
   g_return_val_if_fail (variable != NULL, FALSE);
   g_return_val_if_fail (value != NULL, FALSE);
 
+  if (value == NULL)
+    value = &tmp_val;
+  if (flags == NULL)
+    flags = &tmp_flags;
+
   for (i = 0; i < 256 && object != NULL; i++) {
-    if (swfdec_as_object_lookup (object, variable, value, flags))
+    klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
+    if (klass->get (object, variable, value, flags))
       return TRUE;
     object = object->prototype;
   }
@@ -351,37 +348,21 @@ swfdec_as_object_get_variable_and_flags 
     return FALSE;
   }
   //SWFDEC_WARNING ("no such variable %s", variable);
-  if (value)
-    SWFDEC_AS_VALUE_SET_UNDEFINED (value);
-  if (flags)
-    *flags = 0;
+  SWFDEC_AS_VALUE_SET_UNDEFINED (value);
+  *flags = 0;
   return FALSE;
 }
 
-void
+gboolean
 swfdec_as_object_delete_variable (SwfdecAsObject *object, const char *variable)
 {
   SwfdecAsObjectClass *klass;
-  guint i, flags;
 
-  g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
-  g_return_if_fail (variable != NULL);
+  g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), FALSE);
+  g_return_val_if_fail (variable != NULL, FALSE);
 
-  for (i = 0; i < 256 && object != NULL; i++) {
-    if (!swfdec_as_object_lookup (object, variable, NULL, &flags)) {
-      object = object->prototype;
-      continue;
-    }
-    if (!(flags & SWFDEC_AS_VARIABLE_PERMANENT)) {
-      klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
-      klass->delete (object, variable);
-    }
-    return;
-  }
-  if (i == 256) {
-    swfdec_as_context_abort (object->context, "Prototype recursion limit exceeded");
-    return;
-  }
+  klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
+  return klass->delete (object, variable);
 }
 
 /**
@@ -674,7 +655,7 @@ swfdec_as_object_hasOwnProperty (SwfdecA
 
   name = swfdec_as_value_to_string (object->context, &argv[0]);
   
-  if (swfdec_as_object_lookup (object, name, NULL, &flags) &&
+  if (swfdec_as_object_get_variable_and_flags (object, name, NULL, &flags) &&
       (flags & SWFDEC_AS_VARIABLE_NATIVE) == 0)
     SWFDEC_AS_VALUE_SET_BOOLEAN (retval, TRUE);
   else
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index 2fc8704..3ce58c5 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -80,8 +80,8 @@ struct _SwfdecAsObjectClass {
 						 const char *		variable,
 						 guint			flags,
 						 guint			mask);
-  /* delete the variable - it does exists */
-  void			(* delete)		(SwfdecAsObject *       object,
+  /* delete the variable - return TRUE if it exists */
+  gboolean		(* delete)		(SwfdecAsObject *       object,
 						 const char *		variable);
   /* call with every variable until func returns FALSE */
   gboolean		(* foreach)		(SwfdecAsObject *	object,
@@ -119,7 +119,7 @@ gboolean	swfdec_as_object_get_variable_a
 						 const char *		variable,
 						 SwfdecAsValue *	value,
 						 guint *		flags);
-void		swfdec_as_object_delete_variable(SwfdecAsObject *	object,
+gboolean	swfdec_as_object_delete_variable(SwfdecAsObject *	object,
 						 const char *		variable);
 void		swfdec_as_object_set_variable_flags
 						(SwfdecAsObject *       object,
diff --git a/libswfdec/swfdec_as_super.c b/libswfdec/swfdec_as_super.c
index 6f5902f..72dc8d2 100644
--- a/libswfdec/swfdec_as_super.c
+++ b/libswfdec/swfdec_as_super.c
@@ -94,10 +94,11 @@ swfdec_as_super_set_flags (SwfdecAsObjec
   /* if we have no variables, we also can't set its flags... */
 }
 
-static void
+static gboolean
 swfdec_as_super_delete (SwfdecAsObject *object, const char *variable)
 {
   /* if we have no variables... */
+  return FALSE;
 }
 
 static void
diff --git a/libswfdec/swfdec_as_with.c b/libswfdec/swfdec_as_with.c
index e292af4..fa02b0d 100644
--- a/libswfdec/swfdec_as_with.c
+++ b/libswfdec/swfdec_as_with.c
@@ -67,13 +67,12 @@ swfdec_as_with_set_flags (SwfdecAsObject
   klass->set_flags (with->object, variable, flags, mask);
 }
 
-static void
+static gboolean
 swfdec_as_with_delete (SwfdecAsObject *object, const char *variable)
 {
   SwfdecAsWith *with = SWFDEC_AS_WITH (object);
-  SwfdecAsObjectClass *klass = SWFDEC_AS_OBJECT_GET_CLASS (with->object);
 
-  klass->delete (with->object, variable);
+  return swfdec_as_object_delete_variable (with->object, variable);
 }
 
 static gboolean
diff-tree 092b1c745bb08393fb2ea512cfba6fb0df6ae81d (from fd685fdf3f91154644283ef97d382fe7da480e19)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 10:16:53 2007 +0200

    check that prototypes are used in With statements

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index dd0ea9b..d85db0f 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -379,6 +379,13 @@ EXTRA_DIST = \
 	unescape2-7.swf \
 	unescape2-7.swf.trace \
 	video.flv \
+	with-prototypes.as \
+	with-prototypes-5.swf \
+	with-prototypes-5.swf.trace \
+	with-prototypes-6.swf \
+	with-prototypes-6.swf.trace \
+	with-prototypes-7.swf \
+	with-prototypes-7.swf.trace \
 	xscale.swf \
 	xscale.swf.trace
 
diff --git a/test/trace/with-prototypes-5.swf b/test/trace/with-prototypes-5.swf
new file mode 100644
index 0000000..113132a
Binary files /dev/null and b/test/trace/with-prototypes-5.swf differ
diff --git a/test/trace/with-prototypes-5.swf.trace b/test/trace/with-prototypes-5.swf.trace
new file mode 100644
index 0000000..1ab70b5
--- /dev/null
+++ b/test/trace/with-prototypes-5.swf.trace
@@ -0,0 +1,3 @@
+Check prototypes get used in With
+1
+2
diff --git a/test/trace/with-prototypes-6.swf b/test/trace/with-prototypes-6.swf
new file mode 100644
index 0000000..a0adce8
Binary files /dev/null and b/test/trace/with-prototypes-6.swf differ
diff --git a/test/trace/with-prototypes-6.swf.trace b/test/trace/with-prototypes-6.swf.trace
new file mode 100644
index 0000000..1ab70b5
--- /dev/null
+++ b/test/trace/with-prototypes-6.swf.trace
@@ -0,0 +1,3 @@
+Check prototypes get used in With
+1
+2
diff --git a/test/trace/with-prototypes-7.swf b/test/trace/with-prototypes-7.swf
new file mode 100644
index 0000000..2a9c0a6
Binary files /dev/null and b/test/trace/with-prototypes-7.swf differ
diff --git a/test/trace/with-prototypes-7.swf.trace b/test/trace/with-prototypes-7.swf.trace
new file mode 100644
index 0000000..1ab70b5
--- /dev/null
+++ b/test/trace/with-prototypes-7.swf.trace
@@ -0,0 +1,3 @@
+Check prototypes get used in With
+1
+2
diff --git a/test/trace/with-prototypes.as b/test/trace/with-prototypes.as
new file mode 100644
index 0000000..5ff702a
--- /dev/null
+++ b/test/trace/with-prototypes.as
@@ -0,0 +1,14 @@
+// makeswf -v 7 -s 200x150 -r 1 -o with-prototypes.swf with-prototypes.as
+
+trace ("Check prototypes get used in With");
+x = 0;
+_global.x = -1;
+o = new Object ();
+o.__proto__ = { x: 1 };
+with (o) {
+  trace (x);
+  o.x = 2;
+  trace (x);
+};
+
+loadMovie ("FSCommand:quit", "");
diff-tree fd685fdf3f91154644283ef97d382fe7da480e19 (from 466b3016671ffa1985339c0fe3075cc19e32f3c7)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 10:14:24 2007 +0200

    try to get variables also from prototypes

diff --git a/libswfdec/swfdec_as_with.c b/libswfdec/swfdec_as_with.c
index b5c6ce1..e292af4 100644
--- a/libswfdec/swfdec_as_with.c
+++ b/libswfdec/swfdec_as_with.c
@@ -43,9 +43,8 @@ swfdec_as_with_get (SwfdecAsObject *obje
   SwfdecAsValue *val, guint *flags)
 {
   SwfdecAsWith *with = SWFDEC_AS_WITH (object);
-  SwfdecAsObjectClass *klass = SWFDEC_AS_OBJECT_GET_CLASS (with->object);
 
-  return klass->get (with->object, variable, val, flags);
+  return swfdec_as_object_get_variable_and_flags (with->object, variable, val, flags);
 }
 
 static void
diff-tree 466b3016671ffa1985339c0fe3075cc19e32f3c7 (from f1f78721fb699bbb94bb90edb82b2bbbe203b284)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 10:11:03 2007 +0200

    add swfdec_as_object_get_variable_and_flags()
    
    The variable get/set API needs some overhaul I think

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index a495ed4..567ff16 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -332,8 +332,8 @@ swfdec_as_object_lookup (SwfdecAsObject 
 }
 
 gboolean
-swfdec_as_object_get_variable (SwfdecAsObject *object, 
-    const char *variable, SwfdecAsValue *value)
+swfdec_as_object_get_variable_and_flags (SwfdecAsObject *object, 
+    const char *variable, SwfdecAsValue *value, guint *flags)
 {
   guint i;
 
@@ -342,7 +342,7 @@ swfdec_as_object_get_variable (SwfdecAsO
   g_return_val_if_fail (value != NULL, FALSE);
 
   for (i = 0; i < 256 && object != NULL; i++) {
-    if (swfdec_as_object_lookup (object, variable, value, NULL))
+    if (swfdec_as_object_lookup (object, variable, value, flags))
       return TRUE;
     object = object->prototype;
   }
@@ -351,7 +351,10 @@ swfdec_as_object_get_variable (SwfdecAsO
     return FALSE;
   }
   //SWFDEC_WARNING ("no such variable %s", variable);
-  SWFDEC_AS_VALUE_SET_UNDEFINED (value);
+  if (value)
+    SWFDEC_AS_VALUE_SET_UNDEFINED (value);
+  if (flags)
+    *flags = 0;
   return FALSE;
 }
 
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index a9b637d..2fc8704 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -112,9 +112,13 @@ void		swfdec_as_object_unroot	  	(Swfdec
 void		swfdec_as_object_set_variable	(SwfdecAsObject *	object,
 						 const char *		variable,
 						 const SwfdecAsValue *	value);
-gboolean	swfdec_as_object_get_variable	(SwfdecAsObject *	object,
+#define swfdec_as_object_get_variable(object, variable, value) \
+  swfdec_as_object_get_variable_and_flags (object, variable, value, NULL)
+gboolean	swfdec_as_object_get_variable_and_flags
+						(SwfdecAsObject *	object,
 						 const char *		variable,
-						 SwfdecAsValue *	value);
+						 SwfdecAsValue *	value,
+						 guint *		flags);
 void		swfdec_as_object_delete_variable(SwfdecAsObject *	object,
 						 const char *		variable);
 void		swfdec_as_object_set_variable_flags
diff-tree f1f78721fb699bbb94bb90edb82b2bbbe203b284 (from 7311076213bb5ceb0c56b64632ea4e0b07c21d72)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 10:00:16 2007 +0200

    remove swfdec_as_object_find_variable and use swfdec_as_object_get_variable instead

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index de18973..de0dbd7 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -195,17 +195,16 @@ swfdec_as_frame_set_this (SwfdecAsFrame 
 SwfdecAsObject *
 swfdec_as_frame_find_variable (SwfdecAsFrame *frame, const char *variable)
 {
-  SwfdecAsObject *ret = NULL;
   SwfdecAsScope *cur;
   guint i;
+  SwfdecAsValue val;
 
   g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL);
   g_return_val_if_fail (variable != NULL, NULL);
 
   cur = frame->scope;
   for (i = 0; i < 256; i++) {
-    ret = swfdec_as_object_find_variable (SWFDEC_AS_OBJECT (cur), variable);
-    if (ret)
+    if (swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (cur), variable, &val))
       return SWFDEC_AS_OBJECT (cur);
     if (cur->next == NULL)
       break;
@@ -219,18 +218,18 @@ swfdec_as_frame_find_variable (SwfdecAsF
   /* we've walked the scope chain down. Now look in the special objects. */
   /* 1) the target set via SetTarget */
   if (frame->target) {
-    ret = swfdec_as_object_find_variable (frame->target, variable);
-    if (ret)
+    if (swfdec_as_object_get_variable (frame->target, variable, &val))
       return frame->target;
   } else {
     /* The default target is the original object that called into us */
-    ret = swfdec_as_object_find_variable (SWFDEC_AS_FRAME (cur)->thisp, variable);
-    if (ret)
+    if (swfdec_as_object_get_variable (SWFDEC_AS_FRAME (cur)->thisp, variable, &val))
       return SWFDEC_AS_FRAME (cur)->thisp;
   }
   /* 2) the global object */
-  ret = swfdec_as_object_find_variable (SWFDEC_AS_OBJECT (frame)->context->global, variable);
-  return ret ? SWFDEC_AS_OBJECT (frame)->context->global : NULL;
+  if (swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (frame)->context->global, variable, &val))
+    return SWFDEC_AS_OBJECT (frame)->context->global;
+
+  return NULL;
 }
 
 /**
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index bdfe5d3..a495ed4 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -381,27 +381,6 @@ swfdec_as_object_delete_variable (Swfdec
   }
 }
 
-SwfdecAsObject *
-swfdec_as_object_find_variable (SwfdecAsObject *object,
-    const char *variable)
-{
-  guint i;
-
-  g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL);
-  g_return_val_if_fail (variable != NULL, NULL);
-
-  for (i = 0; i < 256 && object != NULL; i++) {
-    if (swfdec_as_object_lookup (object, variable, NULL, NULL))
-      return object;
-    object = object->prototype;
-  }
-  if (i == 256) {
-    swfdec_as_context_abort (object->context, "Prototype recursion limit exceeded");
-    return NULL;
-  }
-  return NULL;
-}
-
 /**
  * swfdec_as_object_set_variable_flags:
  * @object: a #SwfdecAsObject
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index c703fb0..a9b637d 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -117,8 +117,6 @@ gboolean	swfdec_as_object_get_variable	(
 						 SwfdecAsValue *	value);
 void		swfdec_as_object_delete_variable(SwfdecAsObject *	object,
 						 const char *		variable);
-SwfdecAsObject *swfdec_as_object_find_variable	(SwfdecAsObject *	object,
-						 const char *		variable);
 void		swfdec_as_object_set_variable_flags
 						(SwfdecAsObject *       object,
 						 const char *		variable,
diff-tree 7311076213bb5ceb0c56b64632ea4e0b07c21d72 (from 777b3d0c598129177ec806335ba681b41fd1d239)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jun 6 09:59:34 2007 +0200

    Fix comment

diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h
index c2423e3..7bb41b4 100644
--- a/libswfdec/swfdec_as_frame.h
+++ b/libswfdec/swfdec_as_frame.h
@@ -49,7 +49,7 @@ struct _SwfdecAsFrame {
   char *		function_name;	/* name of function */
   /* normal execution */
   SwfdecScript *	script;		/* script being executed */
-  SwfdecAsScope *	scope;		/* first object in scope chain (can be NULL) */
+  SwfdecAsScope *	scope;		/* first object in scope chain (either this frame or a with object) */
   SwfdecAsObject *	target;		/* target to use instead of last object in scope chain */
   SwfdecAsObject *	var_object;	/* new variables go here */
   SwfdecAsValue *	registers;	/* the registers */


More information about the Swfdec mailing list