[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