[Swfdec] 3 commits - libswfdec/swfdec_js.c
libswfdec/swfdec_js_movie.c libswfdec/swfdec_script.c
Benjamin Otte
company at kemper.freedesktop.org
Thu Feb 22 10:26:42 PST 2007
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 at 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 at 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 at 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);
}
More information about the Swfdec
mailing list