Benjamin Otte
2007-Mar-05 13:10 UTC
[Swfdec] 5 commits - libswfdec/swfdec_js.h libswfdec/swfdec_js_movie.c libswfdec/swfdec_script.c test/trace
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@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@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@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@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@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 },
Reasonably Related Threads
- 17 commits - libswfdec/js libswfdec/swfdec_js.c libswfdec/swfdec_js_global.c libswfdec/swfdec_js.h libswfdec/swfdec_js_movie.c libswfdec/swfdec_movie.c libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_root_movie.c
- Branch 'interpreter' - 18 commits - libswfdec/swfdec_image.c libswfdec/swfdec_image.h libswfdec/swfdec_js.c libswfdec/swfdec_js_color.c libswfdec/swfdec_js_sound.c libswfdec/swfdec_pattern.c libswfdec/swfdec_scriptable.c libswfdec/swfdec_script.c
- 3 commits - libswfdec/swfdec_js.c libswfdec/swfdec_js_movie.c libswfdec/swfdec_script.c
- 10 commits - libswfdec/js libswfdec/swfdec_js_color.c libswfdec/swfdec_js_connection.c libswfdec/swfdec_js_movie.c libswfdec/swfdec_js_net_stream.c libswfdec/swfdec_js_video.c libswfdec/swfdec_js_xml.c libswfdec/swfdec_script.c player/.gitignore
- 22 commits - libswfdec/js libswfdec/swfdec_debugger.c libswfdec/swfdec_js.c libswfdec/swfdec_js_global.c libswfdec/swfdec_js_movie.c libswfdec/swfdec_movie.c libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_script.c