[Swfdec] Branch 'as' - 9 commits - libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_function.c libswfdec/swfdec_as_function.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_native_function.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_script_function.c libswfdec/swfdec_as_super.c libswfdec/swfdec_as_super.h libswfdec/swfdec_debug.c libswfdec/swfdec_debug.h test/trace

Benjamin Otte company at kemper.freedesktop.org
Tue May 22 05:01:36 PDT 2007


 libswfdec/swfdec_as_frame.c                      |   32 ++++++++--------
 libswfdec/swfdec_as_function.c                   |   13 ++++--
 libswfdec/swfdec_as_function.h                   |    4 +-
 libswfdec/swfdec_as_interpret.c                  |   12 ++++--
 libswfdec/swfdec_as_native_function.c            |    3 +
 libswfdec/swfdec_as_object.c                     |   27 ++++++++++++-
 libswfdec/swfdec_as_script_function.c            |    3 +
 libswfdec/swfdec_as_super.c                      |   45 +++++++++++++++++++++--
 libswfdec/swfdec_as_super.h                      |   11 +++--
 libswfdec/swfdec_debug.c                         |    5 +-
 libswfdec/swfdec_debug.h                         |    5 ++
 test/trace/Makefile.am                           |    7 +++
 test/trace/callmethod-undefined-this-5.swf       |binary
 test/trace/callmethod-undefined-this-5.swf.trace |    5 ++
 test/trace/callmethod-undefined-this-6.swf       |binary
 test/trace/callmethod-undefined-this-6.swf.trace |    5 ++
 test/trace/callmethod-undefined-this-7.swf       |binary
 test/trace/callmethod-undefined-this-7.swf.trace |    5 ++
 test/trace/callmethod-undefined-this.as          |   23 +++++++++++
 19 files changed, 165 insertions(+), 40 deletions(-)

New commits:
diff-tree 67d689d2c9390a5520e4ccfe9a28313f2e60f1bb (from 847ef5da65038fc6d85ef9c4a13e9ae62a5bca99)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue May 22 14:01:12 2007 +0200

    fix up super object some more

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 9f99031..3c5fe2c 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -297,16 +297,14 @@ swfdec_as_frame_preload (SwfdecAsFrame *
       swfdec_as_object_set_variable (object, SWFDEC_AS_STR_arguments, &val);
     }
   }
-  if (script->flags & SWFDEC_SCRIPT_PRELOAD_SUPER) {
-    SwfdecAsObject *super = swfdec_as_super_new (object->context);
+  if (!(script->flags & SWFDEC_SCRIPT_SUPPRESS_SUPER)) {
+    SwfdecAsObject *super = swfdec_as_super_new (frame);
     if (super) {
-      SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], super);
-    }
-  } else if (!(script->flags & SWFDEC_SCRIPT_SUPPRESS_SUPER)) {
-    SwfdecAsObject *super = swfdec_as_super_new (object->context);
-    if (super) {
-      SWFDEC_AS_VALUE_SET_OBJECT (&val, super);
-      swfdec_as_object_set_variable (object, SWFDEC_AS_STR_super, &val);
+      if (script->flags & SWFDEC_SCRIPT_PRELOAD_SUPER) {
+	SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], super);
+      } else {
+	swfdec_as_object_set_variable (object, SWFDEC_AS_STR_super, &val);
+      }
     }
   }
   if (script->flags & SWFDEC_SCRIPT_PRELOAD_ROOT) {
diff --git a/libswfdec/swfdec_as_super.c b/libswfdec/swfdec_as_super.c
index 3311bcd..e5b9728 100644
--- a/libswfdec/swfdec_as_super.c
+++ b/libswfdec/swfdec_as_super.c
@@ -29,11 +29,32 @@
 #include "swfdec_as_function.h"
 #include "swfdec_debug.h"
 
-G_DEFINE_TYPE (SwfdecAsSuper, swfdec_as_super, SWFDEC_TYPE_AS_OBJECT)
+G_DEFINE_TYPE (SwfdecAsSuper, swfdec_as_super, SWFDEC_TYPE_AS_FUNCTION)
+
+static SwfdecAsFrame *
+swfdec_as_super_call (SwfdecAsFunction *function)
+{
+  SwfdecAsSuper *super = SWFDEC_AS_SUPER (function);
+  SwfdecAsFunctionClass *klass;
+  SwfdecAsFrame *frame;
+
+  if (super->constructor == NULL) {
+    SWFDEC_FIXME ("figure out what happens when super doesn't have a constructor");
+    return NULL;
+  }
+  klass = SWFDEC_AS_FUNCTION_GET_CLASS (super->constructor);
+  frame = klass->call (super->constructor);
+  /* FIXME: this is ugly */
+  swfdec_as_frame_set_this (frame, super->object);
+  return frame;
+}
 
 static void
 swfdec_as_super_class_init (SwfdecAsSuperClass *klass)
 {
+  SwfdecAsFunctionClass *function_class = SWFDEC_AS_FUNCTION_CLASS (klass);
+
+  function_class->call = swfdec_as_super_call;
 }
 
 static void
@@ -42,15 +63,33 @@ swfdec_as_super_init (SwfdecAsSuper *sup
 }
 
 SwfdecAsObject *
-swfdec_as_super_new (SwfdecAsContext *context)
+swfdec_as_super_new (SwfdecAsFrame *frame)
 {
+  SwfdecAsContext *context;
+  SwfdecAsSuper *super;
   SwfdecAsObject *ret;
 
-  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
+  g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL);
   
+  context = SWFDEC_AS_OBJECT (frame)->context;
   if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsSuper)))
     return NULL;
   ret = g_object_new (SWFDEC_TYPE_AS_SUPER, NULL);
+  super = SWFDEC_AS_SUPER (ret);
+  if (frame->thisp) {
+    SwfdecAsValue val;
+    super->object = frame->thisp;
+    swfdec_as_object_get_variable (frame->thisp, SWFDEC_AS_STR_constructor, &val);
+    if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) {
+      SwfdecAsObject *constructor = SWFDEC_AS_VALUE_GET_OBJECT (&val);
+      swfdec_as_object_get_variable (constructor, SWFDEC_AS_STR___constructor__, &val);
+      if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) {
+	super->constructor = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&val);
+	if (!SWFDEC_IS_AS_FUNCTION (super->constructor))
+	  super->constructor = NULL;
+      }
+    }
+  }
   swfdec_as_object_add (ret, context, sizeof (SwfdecAsSuper));
   return ret;
 }
diff --git a/libswfdec/swfdec_as_super.h b/libswfdec/swfdec_as_super.h
index eb5c673..2545fe7 100644
--- a/libswfdec/swfdec_as_super.h
+++ b/libswfdec/swfdec_as_super.h
@@ -20,7 +20,7 @@
 #ifndef _SWFDEC_AS_SUPER_H_
 #define _SWFDEC_AS_SUPER_H_
 
-#include <libswfdec/swfdec_as_object.h>
+#include <libswfdec/swfdec_as_function.h>
 #include <libswfdec/swfdec_as_types.h>
 
 G_BEGIN_DECLS
@@ -36,16 +36,19 @@ typedef struct _SwfdecAsSuperClass Swfde
 #define SWFDEC_AS_SUPER_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_SUPER, SwfdecAsSuperClass))
 
 struct _SwfdecAsSuper {
-  SwfdecAsObject	object;
+  SwfdecAsFunction	function;
+
+  SwfdecAsFunction *	constructor;	/* super function or NULL */
+  SwfdecAsObject *	object;		/* object super was called on or NULL */
 };
 
 struct _SwfdecAsSuperClass {
-  SwfdecAsObjectClass	object_class;
+  SwfdecAsFunctionClass	function_class;
 };
 
 GType		swfdec_as_super_get_type	(void);
 
-SwfdecAsObject *swfdec_as_super_new		(SwfdecAsContext *	context);
+SwfdecAsObject *swfdec_as_super_new		(SwfdecAsFrame *	frame);
 
 
 G_END_DECLS
diff-tree 847ef5da65038fc6d85ef9c4a13e9ae62a5bca99 (from 9cb22649fde6a503bb6c9be05db5350fcbe538e1)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue May 22 12:51:16 2007 +0200

    change how frames get created and pushed onto the stack

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index a00ad65..9f99031 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -119,8 +119,6 @@ swfdec_as_frame_new (SwfdecAsContext *co
     return NULL;
   frame = g_object_new (SWFDEC_TYPE_AS_FRAME, NULL);
   swfdec_as_object_add (SWFDEC_AS_OBJECT (frame), context, size);
-  frame->next = context->frame;
-  context->frame = frame;
   frame->script = swfdec_script_ref (script);
   frame->function_name = script->name;
   SWFDEC_DEBUG ("new frame for function %s", frame->function_name);
@@ -158,8 +156,6 @@ swfdec_as_frame_new_native (SwfdecAsCont
   frame = g_object_new (SWFDEC_TYPE_AS_FRAME, NULL);
   SWFDEC_DEBUG ("new native frame");
   swfdec_as_object_add (SWFDEC_AS_OBJECT (frame), context, size);
-  frame->next = context->frame;
-  context->frame = frame;
   return frame;
 }
 
diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index ceae2d4..8a27b9f 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -83,8 +83,10 @@ swfdec_as_function_call (SwfdecAsFunctio
   SWFDEC_AS_VALUE_SET_UNDEFINED (return_value);
   klass = SWFDEC_AS_FUNCTION_GET_CLASS (function);
   g_assert (klass->call);
-  klass->call (function);
-  frame = context->frame;
+  frame = klass->call (function);
+  /* FIXME: figure out what to do in these situations */
+  if (frame == NULL)
+    return;
   if (thisp)
     swfdec_as_frame_set_this (frame, thisp);
   frame->var_object = SWFDEC_AS_OBJECT (frame);
@@ -93,6 +95,9 @@ swfdec_as_function_call (SwfdecAsFunctio
   frame->return_value = return_value;
   frame->function = function;
   swfdec_as_frame_preload (frame);
+  /* FIXME: make this a seperate function? */
+  frame->next = context->frame;
+  context->frame = frame;
 }
 
 /*** AS CODE ***/
diff --git a/libswfdec/swfdec_as_function.h b/libswfdec/swfdec_as_function.h
index ddc92d9..456f77a 100644
--- a/libswfdec/swfdec_as_function.h
+++ b/libswfdec/swfdec_as_function.h
@@ -43,8 +43,8 @@ struct _SwfdecAsFunction {
 struct _SwfdecAsFunctionClass {
   SwfdecAsObjectClass	object_class;
 
-  /* call this function: push a new frame onto the stack */
-  void			(* call)			(SwfdecAsFunction *	function);
+  /* return a frame that calls this function or NULL if uncallable */
+  SwfdecAsFrame *	(* call)			(SwfdecAsFunction *	function);
 };
 
 GType			swfdec_as_function_get_type	(void);
diff --git a/libswfdec/swfdec_as_native_function.c b/libswfdec/swfdec_as_native_function.c
index edc2a09..626a380 100644
--- a/libswfdec/swfdec_as_native_function.c
+++ b/libswfdec/swfdec_as_native_function.c
@@ -29,7 +29,7 @@
 
 G_DEFINE_TYPE (SwfdecAsNativeFunction, swfdec_as_native_function, SWFDEC_TYPE_AS_FUNCTION)
 
-static void
+static SwfdecAsFrame *
 swfdec_as_native_function_call (SwfdecAsFunction *function)
 {
   SwfdecAsNativeFunction *native = SWFDEC_AS_NATIVE_FUNCTION (function);
@@ -38,6 +38,7 @@ swfdec_as_native_function_call (SwfdecAs
   frame = swfdec_as_frame_new_native (SWFDEC_AS_OBJECT (function)->context);
   g_assert (native->name);
   frame->function_name = native->name;
+  return frame;
 }
 
 static void
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index bcfaf42..4e93f63 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -523,6 +523,8 @@ swfdec_as_object_run (SwfdecAsObject *ob
   frame = swfdec_as_frame_new (object->context, script);
   if (frame == NULL)
     return;
+  frame->next = object->context->frame;
+  object->context->frame = frame;
   swfdec_as_frame_set_this (frame, object);
   swfdec_as_frame_preload (frame);
   swfdec_as_context_run (object->context);
diff --git a/libswfdec/swfdec_as_script_function.c b/libswfdec/swfdec_as_script_function.c
index bbe4eec..9278ffe 100644
--- a/libswfdec/swfdec_as_script_function.c
+++ b/libswfdec/swfdec_as_script_function.c
@@ -29,7 +29,7 @@
 
 G_DEFINE_TYPE (SwfdecAsScriptFunction, swfdec_as_script_function, SWFDEC_TYPE_AS_FUNCTION)
 
-static void
+static SwfdecAsFrame *
 swfdec_as_script_function_call (SwfdecAsFunction *function)
 {
   SwfdecAsScriptFunction *script = SWFDEC_AS_SCRIPT_FUNCTION (function);
@@ -38,6 +38,7 @@ swfdec_as_script_function_call (SwfdecAs
   frame = swfdec_as_frame_new (SWFDEC_AS_OBJECT (function)->context, script->script);
   SWFDEC_AS_SCOPE (frame)->next = script->scope;
   frame->scope = SWFDEC_AS_SCOPE (frame);
+  return frame;
 }
 
 static void
diff-tree 9cb22649fde6a503bb6c9be05db5350fcbe538e1 (from 83e3e532b360c88a2cce6b0d389fbf89b10b1279)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue May 22 12:49:52 2007 +0200

    add FIXME category for unimplemented features
    
    See http://bugzilla.gnome.org/show_bug.cgi?id=440389 for rationale

diff --git a/libswfdec/swfdec_debug.c b/libswfdec/swfdec_debug.c
index d18e8a7..54eee5c 100644
--- a/libswfdec/swfdec_debug.c
+++ b/libswfdec/swfdec_debug.c
@@ -1,7 +1,7 @@
 /* Swfdec
  * Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
  *		 2005-2006 Eric Anholt <eric at anholt.net>
- *		      2006 Benjamin Otte <otte at gnome.org>
+ *		 2006-2007 Benjamin Otte <otte at gnome.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -29,6 +29,7 @@
 static const char *swfdec_debug_level_names[] = {
   "NONE ",
   "ERROR",
+  "FIXME",
   "WARN ",
   "INFO ",
   "DEBUG",
@@ -36,7 +37,7 @@ static const char *swfdec_debug_level_na
 };
 
 #ifndef SWFDEC_LEVEL_DEFAULT
-#  define SWFDEC_LEVEL_DEFAULT SWFDEC_LEVEL_ERROR
+#  define SWFDEC_LEVEL_DEFAULT SWFDEC_LEVEL_FIXME
 #endif
 
 static guint swfdec_debug_level = SWFDEC_LEVEL_DEFAULT;
diff --git a/libswfdec/swfdec_debug.h b/libswfdec/swfdec_debug.h
index 913a4bd..b29e2ad 100644
--- a/libswfdec/swfdec_debug.h
+++ b/libswfdec/swfdec_debug.h
@@ -1,7 +1,7 @@
 /* Swfdec
  * Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
  *		 2005-2006 Eric Anholt <eric at anholt.net>
- *		      2006 Benjamin Otte <otte at gnome.org>
+ *		 2006-2007 Benjamin Otte <otte at gnome.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -27,6 +27,7 @@
 enum {
   SWFDEC_LEVEL_NONE = 0,
   SWFDEC_LEVEL_ERROR,
+  SWFDEC_LEVEL_FIXME,
   SWFDEC_LEVEL_WARNING,
   SWFDEC_LEVEL_INFO,
   SWFDEC_LEVEL_DEBUG,
@@ -35,6 +36,8 @@ enum {
 
 #define SWFDEC_ERROR(...) \
   SWFDEC_DEBUG_LEVEL(SWFDEC_LEVEL_ERROR, __VA_ARGS__)
+#define SWFDEC_FIXME(...) \
+  SWFDEC_DEBUG_LEVEL(SWFDEC_LEVEL_FIXME, __VA_ARGS__)
 #define SWFDEC_WARNING(...) \
   SWFDEC_DEBUG_LEVEL(SWFDEC_LEVEL_WARNING, __VA_ARGS__)
 #define SWFDEC_INFO(...) \
diff-tree 83e3e532b360c88a2cce6b0d389fbf89b10b1279 (from 31055e19c934432442047ed20c9a4bf595d11c02)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue May 22 11:46:45 2007 +0200

    fix CallMethod with empty this

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 7862e57..63b53a6 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -659,11 +659,12 @@ swfdec_action_call_method (SwfdecAsConte
     SWFDEC_AS_VALUE_SET_STRING (val, SWFDEC_AS_STR_EMPTY);
   }
   if (obj) {
-    SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_peek (frame->stack, 3), obj);
     if (SWFDEC_AS_VALUE_IS_STRING (val) && 
 	SWFDEC_AS_VALUE_GET_STRING (val) == SWFDEC_AS_STR_EMPTY) {
+      SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (frame->stack, 3));
       SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_peek (frame->stack, 2), obj);
     } else {
+      SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_peek (frame->stack, 3), obj);
       name = swfdec_as_value_to_string (cx, val);
       swfdec_as_object_get_variable (obj, name, swfdec_as_stack_peek (frame->stack, 2));
     }
diff-tree 31055e19c934432442047ed20c9a4bf595d11c02 (from a49ac9b22f3e74ebe36146dd5ae4ff3aaee9fe7c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue May 22 11:46:07 2007 +0200

    set this to undefined if frame->thisp == NULL

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 75e0534..a00ad65 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -273,9 +273,17 @@ swfdec_as_frame_preload (SwfdecAsFrame *
   object = SWFDEC_AS_OBJECT (frame);
   script = frame->script;
   if (script->flags & SWFDEC_SCRIPT_PRELOAD_THIS) {
-    SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], frame->thisp);
+    if (frame->thisp) {
+      SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], frame->thisp);
+    } else {
+      current_reg++;
+    }
   } else if (!(script->flags & SWFDEC_SCRIPT_SUPPRESS_THIS)) {
-    SWFDEC_AS_VALUE_SET_OBJECT (&val, frame->thisp);
+    if (frame->thisp) {
+      SWFDEC_AS_VALUE_SET_OBJECT (&val, frame->thisp);
+    } else {
+      SWFDEC_AS_VALUE_SET_UNDEFINED (&val);
+    }
     swfdec_as_object_set_variable (object, SWFDEC_AS_STR_this, &val);
   }
   if (!(script->flags & SWFDEC_SCRIPT_SUPPRESS_ARGS)) {
diff-tree a49ac9b22f3e74ebe36146dd5ae4ff3aaee9fe7c (from 9027b5e811c294d2804cb6723a1d4be315b16cfb)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue May 22 11:44:28 2007 +0200

    add tests for CallMethod with undefined or empty function name

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index e101ba5..582c598 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -20,6 +20,13 @@ EXTRA_DIST = \
 	callfunction-stack.as \
 	callfunction-stack.swf \
 	callfunction-stack.swf.trace \
+	callmethod-undefined-this-5.swf \
+	callmethod-undefined-this-5.swf.trace \
+	callmethod-undefined-this-6.swf \
+	callmethod-undefined-this-6.swf.trace \
+	callmethod-undefined-this-7.swf \
+	callmethod-undefined-this-7.swf.trace \
+	callmethod-undefined-this.as \
 	case1-6.swf \
 	case1-6.swf.trace \
 	case1-7.swf \
diff --git a/test/trace/callmethod-undefined-this-5.swf b/test/trace/callmethod-undefined-this-5.swf
new file mode 100644
index 0000000..0f47114
Binary files /dev/null and b/test/trace/callmethod-undefined-this-5.swf differ
diff --git a/test/trace/callmethod-undefined-this-5.swf.trace b/test/trace/callmethod-undefined-this-5.swf.trace
new file mode 100644
index 0000000..08ee0cc
--- /dev/null
+++ b/test/trace/callmethod-undefined-this-5.swf.trace
@@ -0,0 +1,5 @@
+Test the behaviour of CallMethod with a function name of undefined or ""
+undefined
+undefined
+undefined
+undefined
diff --git a/test/trace/callmethod-undefined-this-6.swf b/test/trace/callmethod-undefined-this-6.swf
new file mode 100644
index 0000000..d410eea
Binary files /dev/null and b/test/trace/callmethod-undefined-this-6.swf differ
diff --git a/test/trace/callmethod-undefined-this-6.swf.trace b/test/trace/callmethod-undefined-this-6.swf.trace
new file mode 100644
index 0000000..08ee0cc
--- /dev/null
+++ b/test/trace/callmethod-undefined-this-6.swf.trace
@@ -0,0 +1,5 @@
+Test the behaviour of CallMethod with a function name of undefined or ""
+undefined
+undefined
+undefined
+undefined
diff --git a/test/trace/callmethod-undefined-this-7.swf b/test/trace/callmethod-undefined-this-7.swf
new file mode 100644
index 0000000..3fa58b4
Binary files /dev/null and b/test/trace/callmethod-undefined-this-7.swf differ
diff --git a/test/trace/callmethod-undefined-this-7.swf.trace b/test/trace/callmethod-undefined-this-7.swf.trace
new file mode 100644
index 0000000..08ee0cc
--- /dev/null
+++ b/test/trace/callmethod-undefined-this-7.swf.trace
@@ -0,0 +1,5 @@
+Test the behaviour of CallMethod with a function name of undefined or ""
+undefined
+undefined
+undefined
+undefined
diff --git a/test/trace/callmethod-undefined-this.as b/test/trace/callmethod-undefined-this.as
new file mode 100644
index 0000000..b4d7c01
--- /dev/null
+++ b/test/trace/callmethod-undefined-this.as
@@ -0,0 +1,23 @@
+// makeswf -v 7 -s 200x150 -r 1 -o callmethod-undefined-this.swf callmethod-undefined-this.as
+
+trace ("Test the behaviour of CallMethod with a function name of undefined or \"\"");
+function foo () {
+  trace (this);
+  return this;
+};
+asm {
+  push 0, "foo"
+  getvariable
+  push undefined
+  callmethod
+  trace
+};
+asm {
+  push 0, "foo"
+  getvariable
+  push ""
+  callmethod
+  trace
+};
+
+loadMovie ("FSCommand:quit", "");
diff-tree 9027b5e811c294d2804cb6723a1d4be315b16cfb (from parents)
Merge: c78e03276ab1c157055f1de6079469b551f47a46 9611954464237c3162a09458e506840adb0943e5
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue May 22 09:54:04 2007 +0200

    Merge branch 'as' of ssh://company@git.freedesktop.org/git/swfdec into as
    
    Conflicts:
    
    	libswfdec/swfdec_as_native_function.c
    	libswfdec/swfdec_as_script_function.c

diff --cc libswfdec/swfdec_as_object.c
index 1c53e0d,6152d51..bcfaf42
@@@ -21,6 -21,6 +21,8 @@@
  #include "config.h"
  #endif
  
++#include <strings.h>
++
  #include "swfdec_as_object.h"
  #include "swfdec_as_context.h"
  #include "swfdec_as_frame.h"
@@@ -68,10 -68,10 +70,27 @@@
  }
  
  static gboolean
++swfdec_as_object_lookup_case_insensitive (gpointer key, gpointer value, gpointer user_data)
++{
++  return strcasecmp (key, user_data) == 0;
++}
++
++static inline SwfdecAsVariable *
++swfdec_as_object_hash_lookup (SwfdecAsObject *object, const char *variable)
++{
++  SwfdecAsVariable *var = g_hash_table_lookup (object->properties, variable);
++
++  if (var || object->context->version >= 7)
++    return var;
++  var = g_hash_table_find (object->properties, swfdec_as_object_lookup_case_insensitive, (gpointer) variable);
++  return var;
++}
++
++static gboolean
  swfdec_as_object_do_get (SwfdecAsObject *object, const char *variable, 
      SwfdecAsValue *val, guint *flags)
  {
--  SwfdecAsVariable *var = g_hash_table_lookup (object->properties, variable);
++  SwfdecAsVariable *var = swfdec_as_object_hash_lookup (object, variable);
  
    if (var) {
      *val = var->value;
@@@ -95,7 -95,7 +114,7 @@@
      }
    }
  
--  var = g_hash_table_lookup (object->properties, variable);
++  var = swfdec_as_object_hash_lookup (object, variable);
    if (var == NULL) {
      if (!swfdec_as_context_use_mem (object->context, sizeof (SwfdecAsVariable)))
        return;
@@@ -108,7 -108,7 +127,7 @@@
  static void
  swfdec_as_object_do_set_flags (SwfdecAsObject *object, const char *variable, guint flags, guint mask)
  {
--  SwfdecAsVariable *var = g_hash_table_lookup (object->properties, variable);
++  SwfdecAsVariable *var = swfdec_as_object_hash_lookup (object, variable);
  
    if (var)
      var->flags = (var->flags & ~mask) | flags;
diff-tree c78e03276ab1c157055f1de6079469b551f47a46 (from parents)
Merge: 7e50fb0b3be75d76c7da43a8bde818fd37e9cdc0 210bee663edb435f5f15cd5e8e9649faecd982d9
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon May 21 14:43:58 2007 +0200

    Merge branch 'as' of ssh://company@git.freedesktop.org/git/swfdec into as

diff-tree 7e50fb0b3be75d76c7da43a8bde818fd37e9cdc0 (from 91444350cb32843ed2aa0ea386df0ba983a7aec6)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon May 21 14:35:25 2007 +0200

    allow (in theory) passing NULL as this pointer

diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index dd91fcc..972bb0b 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -74,11 +74,11 @@ swfdec_as_function_call (SwfdecAsFunctio
   SwfdecAsFunctionClass *klass;
 
   g_return_if_fail (SWFDEC_IS_AS_FUNCTION (function));
-  g_return_if_fail (SWFDEC_IS_AS_OBJECT (thisp));
+  g_return_if_fail (thisp == NULL || SWFDEC_IS_AS_OBJECT (thisp));
   g_return_if_fail (n_args == 0 || args != NULL);
   g_return_if_fail (return_value != NULL);
 
-  context = thisp->context;
+  context = SWFDEC_AS_OBJECT (function)->context;
   /* just to be sure... */
   SWFDEC_AS_VALUE_SET_UNDEFINED (return_value);
   klass = SWFDEC_AS_FUNCTION_GET_CLASS (function);
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index acdfb74..6e890f6 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -582,13 +582,16 @@ swfdec_action_call (SwfdecAsContext *cx,
   SwfdecAsFrame *frame = cx->frame;
   guint i;
 
-  if (!SWFDEC_AS_VALUE_IS_OBJECT (swfdec_as_stack_peek (frame->stack, 1)) ||
-      !SWFDEC_AS_VALUE_IS_OBJECT (swfdec_as_stack_peek (frame->stack, 2)))
+  if (!SWFDEC_AS_VALUE_IS_OBJECT (swfdec_as_stack_peek (frame->stack, 1)))
     goto error;
   fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (swfdec_as_stack_peek (frame->stack, 1));
   if (!SWFDEC_IS_AS_FUNCTION (fun))
     goto error;
-  thisp = SWFDEC_AS_VALUE_GET_OBJECT (swfdec_as_stack_peek (frame->stack, 2));
+  if (!SWFDEC_AS_VALUE_IS_OBJECT (swfdec_as_stack_peek (frame->stack, 2))) {
+    thisp = NULL;
+  } else {
+    thisp = SWFDEC_AS_VALUE_GET_OBJECT (swfdec_as_stack_peek (frame->stack, 2));
+  }
   swfdec_as_stack_pop_n (frame->stack, 2);
   /* sanitize argument count */
   if (n_args > swfdec_as_stack_get_size (frame->stack))
diff --git a/libswfdec/swfdec_as_native_function.c b/libswfdec/swfdec_as_native_function.c
index b373e3a..dde7652 100644
--- a/libswfdec/swfdec_as_native_function.c
+++ b/libswfdec/swfdec_as_native_function.c
@@ -35,6 +35,10 @@ swfdec_as_native_function_call (SwfdecAs
   SwfdecAsNativeFunction *native = SWFDEC_AS_NATIVE_FUNCTION (function);
   SwfdecAsFrame *frame;
 
+  if (thisp == NULL) {
+    SWFDEC_ERROR ("IMPLEMENT: whoops, this can be empty?!");
+    return;
+  }
   frame = swfdec_as_frame_new_native (thisp);
   g_assert (native->name);
   frame->function_name = native->name;
diff --git a/libswfdec/swfdec_as_script_function.c b/libswfdec/swfdec_as_script_function.c
index 2f75150..9c43713 100644
--- a/libswfdec/swfdec_as_script_function.c
+++ b/libswfdec/swfdec_as_script_function.c
@@ -35,6 +35,10 @@ swfdec_as_script_function_call (SwfdecAs
   SwfdecAsScriptFunction *script = SWFDEC_AS_SCRIPT_FUNCTION (function);
   SwfdecAsFrame *frame;
 
+  if (thisp == NULL) {
+    SWFDEC_ERROR ("IMPLEMENT: whoops, this can be empty?!");
+    return;
+  }
   frame = swfdec_as_frame_new (thisp, script->script);
   SWFDEC_AS_SCOPE (frame)->next = script->scope;
   frame->scope = SWFDEC_AS_SCOPE (frame);


More information about the Swfdec mailing list