Benjamin Otte
2007-Feb-22 10:26 UTC
[Swfdec] 3 commits - libswfdec/swfdec_js.c libswfdec/swfdec_js_movie.c libswfdec/swfdec_script.c
libswfdec/swfdec_js.c | 11 +++ libswfdec/swfdec_js_movie.c | 20 ++++++- libswfdec/swfdec_script.c | 123 +++++++++++++++++++++++++++----------------- 3 files changed, 105 insertions(+), 49 deletions(-) New commits: diff-tree 66851d9bc67c5663464a4c9488235e3c233579a7 (from 3c4a91276dbf607849f02fc9f637f8caf1c339c6) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 22 19:26:37 2007 +0100 implement getNextHighestDepth () diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c index 5b730b3..2296078 100644 --- a/libswfdec/swfdec_js_movie.c +++ b/libswfdec/swfdec_js_movie.c @@ -87,7 +87,7 @@ mc_getBytesLoaded (JSContext *cx, JSObje } static JSBool -mc_getBytesTotal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +mc_getBytesTotal (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { SwfdecMovie *movie; SwfdecDecoder *dec; @@ -101,6 +101,23 @@ mc_getBytesTotal(JSContext *cx, JSObject } static JSBool +mc_getNextHighestDepth (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + SwfdecMovie *movie; + int depth; + + movie = JS_GetPrivate(cx, obj); + if (movie->list) { + depth = SWFDEC_MOVIE (g_list_last (movie->list)->data)->depth + 1; + if (depth < 0) + depth = 0; + } else { + depth = 0; + } + return JS_NewNumberValue (cx, depth, rval); +} + +static JSBool mc_do_goto (JSContext *cx, SwfdecMovie *movie, jsval target) { int32 frame; @@ -488,6 +505,7 @@ static JSFunctionSpec movieclip_methods[ { "eval", swfdec_js_global_eval, 1, 0, 0 }, { "getBytesLoaded", mc_getBytesLoaded, 0, 0, 0 }, { "getBytesTotal", mc_getBytesTotal, 0, 0, 0 }, + { "getNextHighestDepth", mc_getNextHighestDepth, 0, 0, 0 }, { "getProperty", swfdec_js_getProperty, 2, 0, 0 }, { "getURL", swfdec_js_getURL, 2, 0, 0 }, { "gotoAndPlay", mc_gotoAndPlay, 1, 0, 0 }, diff-tree 3c4a91276dbf607849f02fc9f637f8caf1c339c6 (from 27f57143cbff3082c9b565e5256023baaf079140) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 22 18:53:05 2007 +0100 rework SetVariable, SetProperty and GetProperty - try setting an existing property first - use the varobj and not the scopeChain if the property doesn't exist - make GetProperty ("bla", x) work like GetVariable ("bla.$property[x]") - same for SetVariable diff --git a/libswfdec/swfdec_js.c b/libswfdec/swfdec_js.c index ee5c7b7..b9313c1 100644 --- a/libswfdec/swfdec_js.c +++ b/libswfdec/swfdec_js.c @@ -341,9 +341,16 @@ swfdec_js_eval_set_property (JSContext * if (!atom) return JS_FALSE; if (obj == NULL) { - if (cx->fp == NULL || cx->fp->scopeChain == NULL) + JSObject *pobj; + JSProperty *prop; + if (cx->fp == NULL || cx->fp->varobj == NULL) return JS_FALSE; - obj = cx->fp->thisp; + if (!js_FindProperty (cx, (jsid) atom, &obj, &pobj, &prop)) + return JS_FALSE; + if (pobj) + obj = pobj; + else + obj = cx->fp->varobj; } return OBJ_SET_PROPERTY (cx, obj, (jsid) atom, ret); } diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index 83dde3a..d688693 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -701,30 +701,32 @@ swfdec_action_pop (JSContext *cx, guint return JS_TRUE; } -static const char *properties[22] = { - "_x", "_y", "_xscale", "_yscale", "_currentframe", - "_totalframes", "_alpha", "_visible", "_width", "_height", - "_rotation", "_target", "_framesloaded", "_name", "_droptarget", - "_url", "_highquality", "_focusrect", "_soundbuftime", "_quality", - "_xmouse", "_ymouse" -}; - -static JSBool +static const char * swfdec_eval_jsval (JSContext *cx, JSObject *obj, jsval *val) { if (JSVAL_IS_STRING (*val)) { const char *bytes = swfdec_js_to_string (cx, *val); if (bytes == NULL) - return JS_FALSE; + return NULL; *val = swfdec_js_eval (cx, obj, bytes); + return bytes; } else { - if (obj == NULL) + if (obj == NULL) { obj = OBJ_THIS_OBJECT (cx, cx->fp->scopeChain); + } *val = OBJECT_TO_JSVAL (obj); + return "."; } - return JS_TRUE; } +static const char *properties[22] = { + "_x", "_y", "_xscale", "_yscale", "_currentframe", + "_totalframes", "_alpha", "_visible", "_width", "_height", + "_rotation", "_target", "_framesloaded", "_name", "_droptarget", + "_url", "_highquality", "_focusrect", "_soundbuftime", "_quality", + "_xmouse", "_ymouse" +}; + static JSBool swfdec_action_get_property (JSContext *cx, guint action, const guint8 *data, guint len) { @@ -732,27 +734,44 @@ swfdec_action_get_property (JSContext *c SwfdecMovie *movie; JSObject *jsobj; guint32 id; + const char *bytes; - val = cx->fp->sp[-2]; - if (!swfdec_eval_jsval (cx, NULL, &val)) - return JS_FALSE; - movie = swfdec_scriptable_from_jsval (cx, val, SWFDEC_TYPE_MOVIE); - val = JSVAL_VOID; - if (movie == NULL) { - SWFDEC_WARNING ("specified target does not reference a movie clip"); - goto out; - } if (!JS_ValueToECMAUint32 (cx, cx->fp->sp[-1], &id)) return JS_FALSE; - - if (id > (((SwfdecScript *) cx->fp->swf)->version > 4 ? 21 : 18)) + val = cx->fp->sp[-2]; + bytes = swfdec_eval_jsval (cx, NULL, &val); + if (id > (((SwfdecScript *) cx->fp->swf)->version > 4 ? 21 : 18)) { + SWFDEC_WARNING ("trying to SetProperty %u, not allowed", id); goto out; + } - if (!(jsobj = swfdec_scriptable_get_object (SWFDEC_SCRIPTABLE (movie)))) + if (bytes == NULL) return JS_FALSE; + if (*bytes == '\0') { + JSObject *pobj; + JSProperty *prop; + JSAtom *atom = js_Atomize (cx, properties[id], strlen (properties[id]), 0); + if (atom == NULL) + return JS_FALSE; + if (!js_FindProperty (cx, (jsid) atom, &jsobj, &pobj, &prop)) + return JS_FALSE; + if (!prop) + return JS_FALSE; + if (!OBJ_GET_PROPERTY (cx, jsobj, (jsid) prop->id, &val)) + return JS_FALSE; + } else { + movie = swfdec_scriptable_from_jsval (cx, val, SWFDEC_TYPE_MOVIE); + if (movie == NULL) { + SWFDEC_WARNING ("specified target does not reference a movie clip"); + goto out; + } - if (!JS_GetProperty (cx, jsobj, properties[id], &val)) - return JS_FALSE; + jsobj = JSVAL_TO_OBJECT (val); + val = JSVAL_VOID; + + if (!JS_GetProperty (cx, jsobj, properties[id], &val)) + return JS_FALSE; + } out: cx->fp->sp -= 1; @@ -767,23 +786,26 @@ swfdec_action_set_property (JSContext *c SwfdecMovie *movie; JSObject *jsobj; guint32 id; + const char *bytes; val = cx->fp->sp[-3]; - if (!swfdec_eval_jsval (cx, NULL, &val)) + if (!JS_ValueToECMAUint32 (cx, cx->fp->sp[-2], &id)) return JS_FALSE; + bytes = swfdec_eval_jsval (cx, NULL, &val); + if (!bytes) + return JS_FALSE; + if (id > (((SwfdecScript *) cx->fp->swf)->version > 4 ? 21 : 18)) { + SWFDEC_WARNING ("trying to SetProperty %u, not allowed", id); + goto out; + } + if (*bytes == '\0' || *bytes == '.') + val = OBJECT_TO_JSVAL (cx->fp->varobj); movie = swfdec_scriptable_from_jsval (cx, val, SWFDEC_TYPE_MOVIE); if (movie == NULL) { SWFDEC_WARNING ("specified target does not reference a movie clip"); goto out; } - if (!JS_ValueToECMAUint32 (cx, cx->fp->sp[-2], &id)) - return JS_FALSE; - - if (id > (((SwfdecScript *) cx->fp->swf)->version > 4 ? 21 : 18)) - goto out; - - if (!(jsobj = swfdec_scriptable_get_object (SWFDEC_SCRIPTABLE (movie)))) - return JS_FALSE; + jsobj = JSVAL_TO_OBJECT (val); if (!JS_SetProperty (cx, jsobj, properties[id], &cx->fp->sp[-1])) return JS_FALSE; @@ -1256,13 +1278,6 @@ swfdec_action_do_set_target (JSContext * /* FIXME: this whole function stops working the moment it's used together * with With */ - if (target == cx->fp->scopeChain) - return JS_TRUE; - if (target == cx->fp->thisp) { - /* FIXME: will probably break once SetTarget is called inside DefineFunctions */ - cx->fp->scopeChain = cx->fp->thisp; - return JS_TRUE; - } with = js_NewObject(cx, &js_WithClass, target, cx->fp->scopeChain); if (!with) return JS_FALSE; @@ -1271,6 +1286,17 @@ swfdec_action_do_set_target (JSContext * } static JSBool +swfdec_action_do_unset_target (JSContext *cx) +{ + if (JS_GetClass (cx->fp->scopeChain) != &js_WithClass) { + SWFDEC_ERROR ("Cannot unset target: scope chain contains no with object"); + return JS_TRUE; + } + cx->fp->scopeChain = JS_GetParent (cx, cx->fp->scopeChain); + return JS_TRUE; +} + +static JSBool swfdec_action_set_target (JSContext *cx, guint action, const guint8 *data, guint len) { jsval target; @@ -1279,8 +1305,9 @@ swfdec_action_set_target (JSContext *cx, SWFDEC_ERROR ("SetTarget action does not specify a string"); return JS_FALSE; } - /* evaluate relative to this to not get trapped by previous SetTarget calls */ - target = swfdec_js_eval (cx, cx->fp->thisp, (const char *) data); + if (*data == '\0') + return swfdec_action_do_unset_target (cx); + target = swfdec_js_eval (cx, NULL, (const char *) data); if (!JSVAL_IS_OBJECT (target) || JSVAL_IS_NULL (target)) { SWFDEC_WARNING ("target is not an object"); return JS_TRUE; @@ -2601,7 +2628,7 @@ swfdec_script_execute (SwfdecScript *scr frame.callobj = NULL; frame.script = NULL; - frame.varobj = frame.argsobj = NULL; + frame.argsobj = NULL; frame.fun = swfdec_script_ensure_function (script, scriptable); frame.swf = script; frame.constant_pool = NULL; @@ -2621,6 +2648,7 @@ swfdec_script_execute (SwfdecScript *scr frame.objAtomMap = NULL; /* no local scope here */ frame.scopeChain = obj; + frame.varobj = obj; /* allocate stack for variables */ frame.nvars = 4; frame.vars = js_AllocStack (cx, frame.nvars, &mark); diff-tree 27f57143cbff3082c9b565e5256023baaf079140 (from f5d0f071e911b84ac0c2c840d965a7d3f16c4be5) Author: Benjamin Otte <otte@gnome.org> Date: Thu Feb 22 18:34:09 2007 +0100 fix getting the current target, so that it works with scope chains diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index f8a9623..83dde3a 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -137,7 +137,10 @@ swfdec_action_has_register (JSContext *c static SwfdecMovie * swfdec_action_get_target (JSContext *cx) { - JSObject *object = cx->fp->thisp; + JSObject *object = cx->fp->scopeChain; + /* this whole function needs a big FIXME */ + if (JS_GetClass (object) == &js_WithClass) + object = JS_GetPrototype (cx, object); return swfdec_scriptable_from_jsval (cx, OBJECT_TO_JSVAL (object), SWFDEC_TYPE_MOVIE); }
Reasonably Related Threads
- 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
- Branch 'interpreter' - 9 commits - libswfdec/js libswfdec/Makefile.am libswfdec/swfdec_debugger.c libswfdec/swfdec_debugger.h libswfdec/swfdec_edittext_movie.c libswfdec/swfdec_event.c libswfdec/swfdec_js.c libswfdec/swfdec_js_global.c
- 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' - 28 commits - configure.ac libswfdec/js libswfdec/swfdec_buffer.c libswfdec/swfdec_edittext_movie.c libswfdec/swfdec_js.c libswfdec/swfdec_js_global.c libswfdec/swfdec_js.h libswfdec/swfdec_js_movie.c libswfdec/swfdec_player.c
- Branch 'as' - 4 commits - libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_interpret.h libswfdec/swfdec_as_object.c libswfdec/swfdec_as_types.c libswfdec/swfdec_as_types.h