[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