[Swfdec] 5 commits - libswfdec/swfdec_js.h libswfdec/swfdec_js_movie.c libswfdec/swfdec_script.c test/trace

Benjamin Otte company at kemper.freedesktop.org
Mon Mar 5 13:09:52 PST 2007


 libswfdec/swfdec_js.h                         |    2 
 libswfdec/swfdec_js_movie.c                   |    8 +
 libswfdec/swfdec_script.c                     |  121 ++++++++++++++++++++++++--
 test/trace/Makefile.am                        |   11 ++
 test/trace/constructor-prototype.swf          |binary
 test/trace/constructor-prototype.swf.trace    |    4 
 test/trace/function-prototype-chain.swf       |binary
 test/trace/function-prototype-chain.swf.trace |    4 
 8 files changed, 145 insertions(+), 5 deletions(-)

New commits:
diff-tree beacb0853da743a6505e50517683ab6541db0b39 (from 88060782880ed193af1f9d26623af2cbcc474940)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Mar 5 22:09:48 2007 +0100

    add 2 tests for prototypes

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 8322668..d087ed3 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -1,3 +1,10 @@
+if HAVE_MING
+SUBDIRS = ming
+else
+SUBDIRS =
+endif
+DIST_SUBDIRS = ming
+
 check_PROGRAMS = trace
 TESTS = $(check_PROGRAMS)
 
@@ -40,6 +47,8 @@ EXTRA_DIST = \
 	comparisons-6.swf.trace \
 	comparisons-7.swf \
 	comparisons-7.swf.trace \
+	constructor-prototype.swf \
+	constructor-prototype.swf.trace \
 	countdown.swf \
 	countdown.swf.trace \
 	currentframe.swf \
@@ -50,6 +59,8 @@ EXTRA_DIST = \
 	function1.swf.trace \
 	function2.swf \
 	function2.swf.trace \
+	function-prototype-chain.swf \
+	function-prototype-chain.swf.trace \
 	function-undefined.swf \
 	function-undefined.swf.trace \
 	goto1.swf \
diff --git a/test/trace/constructor-prototype.swf b/test/trace/constructor-prototype.swf
new file mode 100755
index 0000000..360a372
Binary files /dev/null and b/test/trace/constructor-prototype.swf differ
diff --git a/test/trace/constructor-prototype.swf.trace b/test/trace/constructor-prototype.swf.trace
new file mode 100755
index 0000000..ca8b34d
--- /dev/null
+++ b/test/trace/constructor-prototype.swf.trace
@@ -0,0 +1,4 @@
+Test that functions defined on the prototype exist in the new object
+created new Test object: [object Object]
+called function test on [object Object]
+fortytwo = 42
diff --git a/test/trace/function-prototype-chain.swf b/test/trace/function-prototype-chain.swf
new file mode 100755
index 0000000..fe94b35
Binary files /dev/null and b/test/trace/function-prototype-chain.swf differ
diff --git a/test/trace/function-prototype-chain.swf.trace b/test/trace/function-prototype-chain.swf.trace
new file mode 100755
index 0000000..21cdb34
--- /dev/null
+++ b/test/trace/function-prototype-chain.swf.trace
@@ -0,0 +1,4 @@
+Check prototype chain of a function
+[type Function]
+[object Object]
+undefined
diff-tree 88060782880ed193af1f9d26623af2cbcc474940 (from 6a0efe188a21080caa1b14ea5416f4aa02713c22)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Mar 5 22:08:33 2007 +0100

    handle constructor prototypes correctly

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 01dd6ae..f00a6f1 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1387,7 +1387,7 @@ static JSBool
 swfdec_action_new_object (JSContext *cx, guint action, const guint8 *data, guint len)
 {
   JSStackFrame *fp = cx->fp;
-  jsval constructor;
+  jsval constructor, proto;
   JSObject *object;
   const JSClass *clasp;
   guint n_args;
@@ -1414,7 +1414,12 @@ swfdec_action_new_object (JSContext *cx,
   if (JS_GetClass (object) != &js_FunctionClass)
     goto fail;
   clasp = ((JSFunction *) JS_GetPrivate (cx, object))->clasp;
-  object = JS_NewObject (cx, clasp, NULL, NULL);
+  if (!JS_GetProperty (cx, object, "prototype", &proto))
+    return JS_FALSE;
+  if (!JSVAL_IS_OBJECT (proto)) {
+    SWFDEC_ERROR ("prototype of %s is not an object", name);
+  }
+  object = JS_NewObject (cx, clasp, JSVAL_IS_OBJECT (proto) ? JSVAL_TO_OBJECT (proto) : NULL, NULL);
   if (object == NULL)
     return JS_FALSE;
   fp->sp[-2] = OBJECT_TO_JSVAL (object);
@@ -1436,7 +1441,7 @@ swfdec_action_new_method (JSContext *cx,
   const char *s;
   guint32 n_args;
   JSObject *object;
-  jsval constructor;
+  jsval constructor, proto;
   const JSClass *clasp;
   
   s = swfdec_js_to_string (cx, fp->sp[-1]);
@@ -1467,7 +1472,12 @@ swfdec_action_new_method (JSContext *cx,
   if (JS_GetClass (object) != &js_FunctionClass)
     goto fail;
   clasp = ((JSFunction *) JS_GetPrivate (cx, object))->clasp;
-  object = JS_NewObject (cx, clasp, NULL, NULL);
+  if (!JS_GetProperty (cx, object, "prototype", &proto))
+    return JS_FALSE;
+  if (!JSVAL_IS_OBJECT (proto)) {
+    SWFDEC_ERROR ("prototype of %s is not an object", s);
+  }
+  object = JS_NewObject (cx, clasp, JSVAL_IS_OBJECT (proto) ? JSVAL_TO_OBJECT (proto) : NULL, NULL);
   if (object == NULL)
     return JS_FALSE;
   fp->sp[-2] = OBJECT_TO_JSVAL (object);
diff-tree 6a0efe188a21080caa1b14ea5416f4aa02713c22 (from 44c86abeeb6f4aac79455c6e7873aaa5ee627f2e)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Mar 5 22:07:49 2007 +0100

    implement TypeOf

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 95fdf80..01dd6ae 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1905,6 +1905,45 @@ swfdec_action_to_number (JSContext *cx, 
   return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);
 }
 
+static JSBool
+swfdec_action_type_of (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+  jsval val;
+  const char *type;
+  JSString *string;
+
+  val = cx->fp->sp[-1];
+  if (JSVAL_IS_NUMBER (val)) {
+    type = "number";
+  } else if (JSVAL_IS_BOOLEAN (val)) {
+    type = "boolean";
+  } else if (JSVAL_IS_STRING (val)) {
+    type = "string";
+  } else if (JSVAL_IS_VOID (val)) {
+    type = "undefined";
+  } else if (JSVAL_IS_NULL (val)) {
+    type = "null";
+  } else if (JSVAL_IS_OBJECT (val)) {
+    JSObject *obj = JSVAL_TO_OBJECT (val);
+    if (swfdec_js_is_movieclip (cx, obj)) {
+      type = "movieclip";
+    } else if (JS_ObjectIsFunction (cx, obj)) {
+      type = "function";
+    } else {
+      type = "object";
+    }
+  } else {
+    g_assert_not_reached ();
+    return JS_FALSE;
+  }
+  /* can't use InternString here because of case sensitivity issues */
+  string = JS_NewStringCopyZ (cx, type);
+  if (string == NULL)
+    return JS_FALSE;
+  cx->fp->sp[-1] = STRING_TO_JSVAL (string);
+  return JS_TRUE;
+}
+
 /*** PRINT FUNCTIONS ***/
 
 static char *
@@ -2260,7 +2299,7 @@ static const SwfdecActionSpec actions[25
   [0x41] = { "DefineLocal2", NULL, 1, 0, { NULL, NULL, swfdec_action_define_local2, swfdec_action_define_local2, swfdec_action_define_local2 } },
   [0x42] = { "InitArray", NULL, -1, 1, { NULL, NULL, swfdec_action_init_array, swfdec_action_init_array, swfdec_action_init_array } },
   [0x43] = { "InitObject", NULL, -1, 1, { NULL, NULL, swfdec_action_init_object, swfdec_action_init_object, swfdec_action_init_object } },
-  [0x44] = { "Typeof", NULL },
+  [0x44] = { "TypeOf", NULL, 1, 1, { NULL, NULL, swfdec_action_type_of, swfdec_action_type_of, swfdec_action_type_of } },
   [0x45] = { "TargetPath", NULL, 1, 1, { NULL, NULL, swfdec_action_target_path, swfdec_action_target_path, swfdec_action_target_path } },
   [0x46] = { "Enumerate", NULL },
   [0x47] = { "Add2", NULL, 2, 1, { NULL, NULL, swfdec_action_add2_5, swfdec_action_add2_5, swfdec_action_add2_7 } },
diff-tree 44c86abeeb6f4aac79455c6e7873aaa5ee627f2e (from 1041f2ee1c6c96ab61e766e968ebb16b2d11cfc7)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Mar 5 22:07:37 2007 +0100

    add swfdec_js_object_is_movieclip

diff --git a/libswfdec/swfdec_js.h b/libswfdec/swfdec_js.h
index f32374b..624cbb3 100644
--- a/libswfdec/swfdec_js.h
+++ b/libswfdec/swfdec_js.h
@@ -62,6 +62,8 @@ void		swfdec_js_eval_set    		(JSContext
 /* support functions */
 const char *	swfdec_js_to_string		(JSContext *		cx,
 						 jsval			val);
+gboolean	swfdec_js_is_movieclip		(JSContext *		cx,
+						 JSObject *		object);
 
 G_END_DECLS
 
diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c
index 855d002..1c4d80a 100644
--- a/libswfdec/swfdec_js_movie.c
+++ b/libswfdec/swfdec_js_movie.c
@@ -1175,3 +1175,11 @@ swfdec_js_movie_remove_property (SwfdecM
   }
 }
 
+gboolean
+swfdec_js_is_movieclip (JSContext *cx, JSObject *object)
+{
+  g_return_val_if_fail (cx != NULL, FALSE);
+  g_return_val_if_fail (object != NULL, FALSE);
+
+  return JS_InstanceOf (cx, object, &movieclip_class, NULL);
+}
diff-tree 1041f2ee1c6c96ab61e766e968ebb16b2d11cfc7 (from 1d7b4569b0f06d928f583a3e779137322aa86448)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Mar 5 18:08:30 2007 +0100

    implement ActionSwap
    
    that was easy

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 7f0a833..95fdf80 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1430,6 +1430,59 @@ fail:
 }
 
 static JSBool
+swfdec_action_new_method (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+  JSStackFrame *fp = cx->fp;
+  const char *s;
+  guint32 n_args;
+  JSObject *object;
+  jsval constructor;
+  const JSClass *clasp;
+  
+  s = swfdec_js_to_string (cx, fp->sp[-1]);
+  if (s == NULL)
+    return JS_FALSE;
+  if (!JS_ValueToECMAUint32 (cx, fp->sp[-3], &n_args))
+    return JS_FALSE;
+  if (n_args + 3 > (guint) (fp->sp - fp->spbase))
+    return JS_FALSE;
+  
+  if (!JS_ValueToObject (cx, fp->sp[-2], &object))
+    return JS_FALSE;
+  if (object == NULL)
+    goto fail;
+  if (s[0] == '\0') {
+    constructor = OBJECT_TO_JSVAL (object);
+  } else {
+    if (!JS_GetProperty (cx, object, s, &constructor))
+      return JS_FALSE;
+    if (!JSVAL_IS_OBJECT (constructor)) {
+      SWFDEC_WARNING ("%s:%s is not a function", JS_GetClass (object)->name, s);
+    }
+  }
+  fp->sp[-1] = OBJECT_TO_JSVAL (constructor);
+  if (!JSVAL_IS_OBJECT (constructor) || JSVAL_IS_NULL (constructor))
+    goto fail;
+  object = JSVAL_TO_OBJECT (constructor);
+  if (JS_GetClass (object) != &js_FunctionClass)
+    goto fail;
+  clasp = ((JSFunction *) JS_GetPrivate (cx, object))->clasp;
+  object = JS_NewObject (cx, clasp, NULL, NULL);
+  if (object == NULL)
+    return JS_FALSE;
+  fp->sp[-2] = OBJECT_TO_JSVAL (object);
+  if (!swfdec_action_call (cx, n_args, JSINVOKE_CONSTRUCT))
+    return JS_FALSE;
+  fp->sp[-1] = OBJECT_TO_JSVAL (object);
+  return JS_TRUE;
+
+fail:
+  fp->sp -= 2 + n_args;
+  fp->sp[-1] = JSVAL_VOID;
+  return JS_TRUE;
+}
+
+static JSBool
 swfdec_action_init_object (JSContext *cx, guint action, const guint8 *data, guint len)
 {
   JSStackFrame *fp = cx->fp;
@@ -1835,6 +1888,15 @@ swfdec_action_modulo_7 (JSContext *cx, g
 }
 
 static JSBool
+swfdec_action_swap (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+  jsval tmp = cx->fp->sp[-2];
+  cx->fp->sp[-2] = cx->fp->sp[-1];
+  cx->fp->sp[-2] = tmp;
+  return JS_TRUE;
+}
+
+static JSBool
 swfdec_action_to_number (JSContext *cx, guint action, const guint8 *data, guint len)
 {
   double d;
@@ -2207,13 +2269,13 @@ static const SwfdecActionSpec actions[25
   [0x4a] = { "ToNumber", NULL, 1, 1, { NULL, NULL, swfdec_action_to_number, swfdec_action_to_number, swfdec_action_to_number } },
   [0x4b] = { "ToString", NULL },
   [0x4c] = { "PushDuplicate", NULL, 1, 2, { NULL, NULL, swfdec_action_push_duplicate, swfdec_action_push_duplicate, swfdec_action_push_duplicate } },
-  [0x4d] = { "Swap", NULL },
+  [0x4d] = { "Swap", NULL, 2, 2, { NULL, NULL, swfdec_action_swap, swfdec_action_swap, swfdec_action_swap } },
   [0x4e] = { "GetMember", NULL, 2, 1, { NULL, swfdec_action_get_member, swfdec_action_get_member, swfdec_action_get_member, swfdec_action_get_member } },
   [0x4f] = { "SetMember", NULL, 3, 0, { NULL, swfdec_action_set_member, swfdec_action_set_member, swfdec_action_set_member, swfdec_action_set_member } },
   [0x50] = { "Increment", NULL, 1, 1, { NULL, NULL, swfdec_action_increment, swfdec_action_increment, swfdec_action_increment } },
   [0x51] = { "Decrement", NULL, 1, 1, { NULL, NULL, swfdec_action_decrement, swfdec_action_decrement, swfdec_action_decrement } },
   [0x52] = { "CallMethod", NULL, -1, 1, { NULL, NULL, swfdec_action_call_method, swfdec_action_call_method, swfdec_action_call_method } },
-  [0x53] = { "NewMethod", NULL },
+  [0x53] = { "NewMethod", NULL, -1, 1, { NULL, NULL, swfdec_action_new_method, swfdec_action_new_method, swfdec_action_new_method } },
   /* version 6 */
   [0x54] = { "InstanceOf", NULL },
   [0x55] = { "Enumerate2", NULL },


More information about the Swfdec mailing list