[Swfdec] 4 commits - libswfdec/swfdec_asbroadcaster.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame_internal.h libswfdec/swfdec_as_function.c libswfdec/swfdec_as_interpret.c test/trace

Pekka Lampila medar at kemper.freedesktop.org
Thu Nov 15 10:58:43 PST 2007


 libswfdec/swfdec_as_frame.c          |   14 ++
 libswfdec/swfdec_as_frame_internal.h |    3 
 libswfdec/swfdec_as_function.c       |   12 --
 libswfdec/swfdec_as_interpret.c      |    1 
 libswfdec/swfdec_asbroadcaster.c     |    3 
 test/trace/arguments-5.swf           |binary
 test/trace/arguments-5.swf.trace     |   82 +++++++++--------
 test/trace/arguments-6.swf           |binary
 test/trace/arguments-6.swf.trace     |  137 ++++++++++++++---------------
 test/trace/arguments-7.swf           |binary
 test/trace/arguments-7.swf.trace     |  137 ++++++++++++++---------------
 test/trace/arguments-8.swf           |binary
 test/trace/arguments-8.swf.trace     |  137 ++++++++++++++---------------
 test/trace/arguments.as              |  165 ++++++++++++++++++-----------------
 14 files changed, 351 insertions(+), 340 deletions(-)

New commits:
commit 15402b24b998b110dad41d2b1559267d474ba892
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Thu Nov 15 20:48:40 2007 +0200

    Improve arguments caller/callee test somewhat

diff --git a/test/trace/arguments-5.swf b/test/trace/arguments-5.swf
index aece37e..50d9be0 100644
Binary files a/test/trace/arguments-5.swf and b/test/trace/arguments-5.swf differ
diff --git a/test/trace/arguments-5.swf.trace b/test/trace/arguments-5.swf.trace
index 02fbeb4..7e8718f 100644
--- a/test/trace/arguments-5.swf.trace
+++ b/test/trace/arguments-5.swf.trace
@@ -2,23 +2,49 @@ Global:
 arguments: 
 caller: 
 callee: 
-Child CallFunction:
+Child:
 arguments: 
 caller: null
-callee: func
-Child CallMethod:
+callee: child
+Run:
 arguments: 
 caller: null
-callee: func
+callee: run
+Child CallFunction:
+arguments: 
+caller: run
+callee: child
+Child CallMethod:
+arguments: 
+caller: run
+callee: child
+
+toString:
+arguments: 
+caller: run
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
+callee: child
+
+valueOf:
+arguments: 
+caller: run
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
+callee: child
 
 Method:
 arguments: 
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Call:
 
@@ -26,12 +52,12 @@ Apply:
 
 Sort:
 arguments: a,
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Timeout:
 arguments: 
@@ -40,4 +66,4 @@ callee: timeout
 Child:
 arguments: 
 caller: timeout
-callee: func
+callee: child
diff --git a/test/trace/arguments-6.swf b/test/trace/arguments-6.swf
index fd10275..c319221 100644
Binary files a/test/trace/arguments-6.swf and b/test/trace/arguments-6.swf differ
diff --git a/test/trace/arguments-6.swf.trace b/test/trace/arguments-6.swf.trace
index 482d59e..6d69d7d 100644
--- a/test/trace/arguments-6.swf.trace
+++ b/test/trace/arguments-6.swf.trace
@@ -2,86 +2,109 @@ Global:
 arguments: 
 caller: 
 callee: 
-Child CallFunction:
+Child:
 arguments: 
 caller: null
-callee: func
-Child CallMethod:
+callee: child
+Run:
 arguments: 
 caller: null
-callee: func
+callee: run
+Child CallFunction:
+arguments: 
+caller: run
+callee: child
+Child CallMethod:
+arguments: 
+caller: run
+callee: child
+
+toString:
+arguments: 
+caller: run
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
+callee: child
+
+valueOf:
+arguments: 
+caller: run
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
+callee: child
 
 Method:
 arguments: 
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Call:
 arguments: 
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Apply:
 arguments: 
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Sort:
 arguments: a,
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Prop set:
 arguments: a,
-caller: null
+caller: run
 callee: prop_set
 Child:
 arguments: 
 caller: prop_set
-callee: func
+callee: child
 
 Prop get:
 arguments: 
-caller: null
+caller: run
 callee: prop_get
 Child:
 arguments: 
 caller: prop_get
-callee: func
+callee: child
 
 Watcher:
 arguments: watched,true,false,
-caller: null
+caller: run
 callee: watcher
 Child:
 arguments: 
 caller: watcher
-callee: func
+callee: child
 
 Broadcast:
 arguments: 
-caller: null
+caller: run
 callee: broadcast
 Child:
-arguments: 
-caller: broadcast
-callee: func
 
 Timeout:
 arguments: 
@@ -90,4 +113,4 @@ callee: timeout
 Child:
 arguments: 
 caller: timeout
-callee: func
+callee: child
diff --git a/test/trace/arguments-7.swf b/test/trace/arguments-7.swf
index ec2528d..6953251 100644
Binary files a/test/trace/arguments-7.swf and b/test/trace/arguments-7.swf differ
diff --git a/test/trace/arguments-7.swf.trace b/test/trace/arguments-7.swf.trace
index dbcd38e..a9c8cb1 100644
--- a/test/trace/arguments-7.swf.trace
+++ b/test/trace/arguments-7.swf.trace
@@ -2,86 +2,109 @@ Global:
 arguments: undefined
 caller: undefined
 callee: undefined
-Child CallFunction:
+Child:
 arguments: 
 caller: null
-callee: func
-Child CallMethod:
+callee: child
+Run:
 arguments: 
 caller: null
-callee: func
+callee: run
+Child CallFunction:
+arguments: 
+caller: run
+callee: child
+Child CallMethod:
+arguments: 
+caller: run
+callee: child
+
+toString:
+arguments: 
+caller: run
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
+callee: child
+
+valueOf:
+arguments: 
+caller: run
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
+callee: child
 
 Method:
 arguments: 
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Call:
 arguments: 
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Apply:
 arguments: 
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Sort:
 arguments: a,undefined
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Prop set:
 arguments: a,undefined
-caller: null
+caller: run
 callee: prop_set
 Child:
 arguments: 
 caller: prop_set
-callee: func
+callee: child
 
 Prop get:
 arguments: 
-caller: null
+caller: run
 callee: prop_get
 Child:
 arguments: 
 caller: prop_get
-callee: func
+callee: child
 
 Watcher:
 arguments: watched,true,false,undefined
-caller: null
+caller: run
 callee: watcher
 Child:
 arguments: 
 caller: watcher
-callee: func
+callee: child
 
 Broadcast:
 arguments: 
-caller: null
+caller: run
 callee: broadcast
 Child:
-arguments: 
-caller: broadcast
-callee: func
 
 Timeout:
 arguments: 
@@ -90,4 +113,4 @@ callee: timeout
 Child:
 arguments: 
 caller: timeout
-callee: func
+callee: child
diff --git a/test/trace/arguments-8.swf b/test/trace/arguments-8.swf
index 08c8d36..37b7b22 100644
Binary files a/test/trace/arguments-8.swf and b/test/trace/arguments-8.swf differ
diff --git a/test/trace/arguments-8.swf.trace b/test/trace/arguments-8.swf.trace
index dbcd38e..a9c8cb1 100644
--- a/test/trace/arguments-8.swf.trace
+++ b/test/trace/arguments-8.swf.trace
@@ -2,86 +2,109 @@ Global:
 arguments: undefined
 caller: undefined
 callee: undefined
-Child CallFunction:
+Child:
 arguments: 
 caller: null
-callee: func
-Child CallMethod:
+callee: child
+Run:
 arguments: 
 caller: null
-callee: func
+callee: run
+Child CallFunction:
+arguments: 
+caller: run
+callee: child
+Child CallMethod:
+arguments: 
+caller: run
+callee: child
+
+toString:
+arguments: 
+caller: run
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
+callee: child
+
+valueOf:
+arguments: 
+caller: run
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
+callee: child
 
 Method:
 arguments: 
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Call:
 arguments: 
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Apply:
 arguments: 
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Sort:
 arguments: a,undefined
-caller: null
+caller: run
 callee: func_and_child
 Child:
 arguments: 
 caller: func_and_child
-callee: func
+callee: child
 
 Prop set:
 arguments: a,undefined
-caller: null
+caller: run
 callee: prop_set
 Child:
 arguments: 
 caller: prop_set
-callee: func
+callee: child
 
 Prop get:
 arguments: 
-caller: null
+caller: run
 callee: prop_get
 Child:
 arguments: 
 caller: prop_get
-callee: func
+callee: child
 
 Watcher:
 arguments: watched,true,false,undefined
-caller: null
+caller: run
 callee: watcher
 Child:
 arguments: 
 caller: watcher
-callee: func
+callee: child
 
 Broadcast:
 arguments: 
-caller: null
+caller: run
 callee: broadcast
 Child:
-arguments: 
-caller: broadcast
-callee: func
 
 Timeout:
 arguments: 
@@ -90,4 +113,4 @@ callee: timeout
 Child:
 arguments: 
 caller: timeout
-callee: func
+callee: child
diff --git a/test/trace/arguments.as b/test/trace/arguments.as
index a7424dd..2354e85 100644
--- a/test/trace/arguments.as
+++ b/test/trace/arguments.as
@@ -1,60 +1,22 @@
 // makeswf -v 7 -r 1 -o test-7.swf test.as
 
-var o = {};
-var tmp = {};
-
-function func () {
+function child () {
   trace ("arguments: " + arguments);
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
 }
-func.valueOf = func.toString = function () { return "func"; };
+child.valueOf = child.toString = function () { return "child"; };
 
 function func_and_child () {
   trace ("arguments: " + arguments);
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
   trace ("Child:");
-  func ();
+  child ();
 }
 func_and_child.valueOf = func_and_child.toString =
   function () { return "func_and_child"; };
 
-
-trace ("Global:");
-trace ("arguments: " + arguments);
-trace ("caller: " + arguments.caller);
-trace ("callee: " + arguments.callee);
-trace ("Child CallFunction:");
-func ();
-trace ("Child CallMethod:");
-o.func = func;
-o.func ();
-
-
-trace ("");
-trace ("Method:");
-o.func_and_child = func_and_child;
-o.func_and_child ();
-
-
-trace ("");
-trace ("Call:");
-func_and_child.call ();
-
-
-trace ("");
-trace ("Apply:");
-func_and_child.apply ();
-
-
-trace ("");
-trace ("Sort:");
-tmp = new Array (2);
-tmp[0] = "a";
-tmp.sort (func_and_child);
-
-
 function prop_get () {
   trace ("");
   trace ("Prop get:");
@@ -62,7 +24,7 @@ function prop_get () {
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
   trace ("Child:");
-  func ();
+  child ();
 }
 prop_get.valueOf = prop_get.toString = function () { return "prop_get"; };
 
@@ -73,15 +35,8 @@ function prop_set () {
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
   trace ("Child:");
-  func ();
+  child ();
 }
-prop_set.valueOf = prop_set.toString = function () { return "prop_set"; };
-
-o.addProperty ("prop", prop_get, prop_set);
-
-o.prop = tmp;
-tmp = o.prop;
-
 
 function watcher () {
   trace ("");
@@ -90,44 +45,115 @@ function watcher () {
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
   trace ("Child:");
-  func ();
+  child ();
 }
 watcher.valueOf = watcher.toString = function () { return "watcher"; };
 
-o.watched = true;
-o.watch ("watched", watcher);
-o.watched = false;
-
-
-var emitter = new Object ();
-AsBroadcaster.initialize (emitter);
-emitter._listeners.push (new Object ());
-emitter._listeners[0].broadcast = function () {
+function timeout () {
   trace ("");
-  trace ("Broadcast:");
+  trace ("Timeout:");
   trace ("arguments: " + arguments);
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
   trace ("Child:");
-  func ();
-};
-emitter._listeners[0].broadcast.valueOf = function () { return "broadcast"; };
-emitter._listeners[0].broadcast.toString = function () { return "broadcast"; };
+  child ();
+
+  loadMovie ("FSCommand:quit", "");
+}
+timeout.valueOf = timeout.toString = function () { return "timeout"; };
 
-emitter.broadcastMessage ("broadcast");
+function run () {
+  var o = {};
+  var tmp = {};
 
 
-function timeout () {
-  trace ("");
-  trace ("Timeout:");
+  trace ("Run:");
   trace ("arguments: " + arguments);
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
-  trace ("Child:");
-  func ();
+  trace ("Child CallFunction:");
+  child ();
+  trace ("Child CallMethod:");
+  o.child = child;
+  o.child ();
 
-  loadMovie ("FSCommand:quit", "");
+
+  o.toString = func_and_child;
+  trace ("");
+  trace ("toString:");
+  tmp = "" + o;
+
+
+  o.valueOf = func_and_child;
+  trace ("");
+  trace ("valueOf:");
+  parseInt.valueOf = parseInt.toString = function () { return "parseInt"; };
+  parseInt (tmp, o);
+
+
+  trace ("");
+  trace ("Method:");
+  o.func_and_child = func_and_child;
+  o.func_and_child ();
+
+
+  trace ("");
+  trace ("Call:");
+  func_and_child.call ();
+
+
+  trace ("");
+  trace ("Apply:");
+  func_and_child.apply ();
+
+
+  trace ("");
+  trace ("Sort:");
+  tmp = new Array (2);
+  tmp[0] = "a";
+  tmp.sort (func_and_child);
+
+
+  prop_set.valueOf = prop_set.toString = function () { return "prop_set"; };
+
+  o.addProperty ("prop", prop_get, prop_set);
+
+  o.prop = tmp;
+  tmp = o.prop;
+
+
+  o.watched = true;
+  o.watch ("watched", watcher);
+  o.watched = false;
+
+
+  var emitter = new Object ();
+  AsBroadcaster.initialize (emitter);
+  emitter._listeners.push (new Object ());
+  emitter._listeners[0].broadcast = function () {
+    trace ("");
+    trace ("Broadcast:");
+    trace ("arguments: " + arguments);
+    trace ("caller: " + arguments.caller);
+    trace ("callee: " + arguments.callee);
+    trace ("Child:");
+    func ();
+  };
+  emitter._listeners[0].broadcast.valueOf = function () { return "broadcast"; };
+  emitter._listeners[0].broadcast.toString = function () { return "broadcast"; };
+
+  emitter.broadcastMessage ("broadcast");
+
+
+  setTimeout (timeout, 0);
 }
-timeout.valueOf = timeout.toString = function () { return "timeout"; };
+run.valueOf = run.toString = function () { return "run"; };
+
+trace ("Global:");
+trace ("arguments: " + arguments);
+trace ("caller: " + arguments.caller);
+trace ("callee: " + arguments.callee);
+trace ("Child:");
+child ();
 
-setTimeout (timeout, 0);
+run ();
commit 734b831b9ec12aa9bb572ff7f3011573f3b89069
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Thu Nov 15 20:47:20 2007 +0200

    Ignore all native functions when setting arguments.caller

diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c
index ed531a7..3c6cde5 100644
--- a/libswfdec/swfdec_as_array.c
+++ b/libswfdec/swfdec_as_array.c
@@ -1228,9 +1228,6 @@ swfdec_as_array_do_sort (SwfdecAsObject *object, gint32 options,
   fdata.compare_custom_func = custom_compare_func;
   fdata.fields = fields;
 
-  // don't mark this function as the caller of custom sort function
-  object->context->frame->caller = FALSE;
-
   // generate fdata.order which points to the values
   if (!swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_populate,
 	&fdata))
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 5f0a40d..16546a5 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -378,7 +378,6 @@ swfdec_as_frame_init (SwfdecAsFrame *frame)
   frame->function_name = "unnamed";
   frame->blocks = g_array_new (FALSE, FALSE, sizeof (SwfdecAsFrameBlock));
   frame->block_end = (gpointer) -1;
-  frame->caller = TRUE;
 }
 
 static void
@@ -699,10 +698,11 @@ swfdec_as_frame_preload (SwfdecAsFrame *frame)
     }
 
     next = frame->next;
-    while (next && next->caller == FALSE) {
+    while (next != NULL && (next->function == NULL ||
+	SWFDEC_IS_AS_NATIVE_FUNCTION (next->function))) {
       next = next->next;
     }
-    if (next != NULL && next->function != NULL) {
+    if (next != NULL) {
       SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (next->function));
     } else {
       SWFDEC_AS_VALUE_SET_NULL (&val);
diff --git a/libswfdec/swfdec_as_frame_internal.h b/libswfdec/swfdec_as_frame_internal.h
index 44a87af..d50a9ce 100644
--- a/libswfdec/swfdec_as_frame_internal.h
+++ b/libswfdec/swfdec_as_frame_internal.h
@@ -33,7 +33,6 @@ struct _SwfdecAsFrame {
 
   SwfdecAsFrame *	next;		/* next frame (FIXME: keep a list in the context instead?) */
   SwfdecAsFunction *	function;	/* function we're executing or NULL if toplevel */
-  gboolean		caller;		/* this function can be used as arguments.caller */
   SwfdecAsObject *	thisp;		/* this object in current frame or NULL if none */
   SwfdecAsObject *	super;		/* super object in current frame or NULL if none */
   gboolean		construct;	/* TRUE if this is the constructor for thisp */
diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index a8f0d66..ca1b735 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -191,7 +191,6 @@ swfdec_as_function_do_call (SwfdecAsContext *cx, SwfdecAsObject *object,
     argc--;
     argv++;
   }
-  cx->frame->caller = FALSE; // don't mark this function as the caller
   swfdec_as_function_call (fun, thisp, argc, argv, ret);
   swfdec_as_context_run (cx);
 }
@@ -239,7 +238,6 @@ swfdec_as_function_apply (SwfdecAsContext *cx, SwfdecAsObject *object,
     }
   }
 
-  cx->frame->caller = FALSE; // don't mark this function as the caller
   swfdec_as_function_call (fun, thisp, length, argv_pass, ret);
   swfdec_as_context_run (cx);
 
diff --git a/libswfdec/swfdec_asbroadcaster.c b/libswfdec/swfdec_asbroadcaster.c
index 61bb6d0..5ea7d58 100644
--- a/libswfdec/swfdec_asbroadcaster.c
+++ b/libswfdec/swfdec_asbroadcaster.c
@@ -73,7 +73,6 @@ broadcastMessage (SwfdecAsContext *cx, SwfdecAsObject *object,
   if (list == NULL)
     return;
 
-  cx->frame->caller = FALSE; // don't mark this function as the caller
   list = g_slist_reverse (list);
   for (walk = list; walk; walk = walk->next) {
     swfdec_as_object_call (walk->data, name, argc, argv, &val);
commit a9bad8ec630dd141be6a516b7cc321f5406b13e6
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Thu Nov 15 20:05:47 2007 +0200

    Rewrite arguments caller/callee test to be much better

diff --git a/test/trace/arguments-5.swf b/test/trace/arguments-5.swf
index 3c8b5c0..aece37e 100644
Binary files a/test/trace/arguments-5.swf and b/test/trace/arguments-5.swf differ
diff --git a/test/trace/arguments-5.swf.trace b/test/trace/arguments-5.swf.trace
index ea28be3..02fbeb4 100644
--- a/test/trace/arguments-5.swf.trace
+++ b/test/trace/arguments-5.swf.trace
@@ -2,62 +2,42 @@ Global:
 arguments: 
 caller: 
 callee: 
-
-Calling from outside of function
-
-CallFunction
+Child CallFunction:
 arguments: 
 caller: null
-callee: 
-
-CallMethod
+callee: func
+Child CallMethod:
 arguments: 
 caller: null
-callee: 
-
-Call:
-
-Apply:
+callee: func
 
-New:
+Method:
 arguments: 
 caller: null
-callee: 
-
-Sort:
-arguments: a,
-caller: null
-callee: 
-
-Calling from inside a function
-
-Check
-
-CallFunction
+callee: func_and_child
+Child:
 arguments: 
-caller: 
-callee: 
-
-CallMethod
-arguments: 
-caller: 
-callee: 
+caller: func_and_child
+callee: func
 
 Call:
 
 Apply:
 
-New:
-arguments: 
-caller: 
-callee: 
-
 Sort:
 arguments: a,
-caller: 
-callee: 
+caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
+callee: func
 
 Timeout:
 arguments: 
 caller: null
-callee: 
+callee: timeout
+Child:
+arguments: 
+caller: timeout
+callee: func
diff --git a/test/trace/arguments-6.swf b/test/trace/arguments-6.swf
index bff66b5..fd10275 100644
Binary files a/test/trace/arguments-6.swf and b/test/trace/arguments-6.swf differ
diff --git a/test/trace/arguments-6.swf.trace b/test/trace/arguments-6.swf.trace
index 3f766da..482d59e 100644
--- a/test/trace/arguments-6.swf.trace
+++ b/test/trace/arguments-6.swf.trace
@@ -2,114 +2,92 @@ Global:
 arguments: 
 caller: 
 callee: 
-
-Calling from outside of function
-
-CallFunction
+Child CallFunction:
 arguments: 
 caller: null
 callee: func
-
-CallMethod
+Child CallMethod:
 arguments: 
 caller: null
 callee: func
 
-Call:
+Method:
 arguments: 
 caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
 callee: func
 
-Apply:
+Call:
 arguments: 
 caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
 callee: func
 
-New:
+Apply:
 arguments: 
 caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
 callee: func
 
 Sort:
 arguments: a,
 caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
 callee: func
 
 Prop set:
-arguments: 2
+arguments: a,
 caller: null
 callee: prop_set
+Child:
+arguments: 
+caller: prop_set
+callee: func
 
 Prop get:
 arguments: 
 caller: null
 callee: prop_get
+Child:
+arguments: 
+caller: prop_get
+callee: func
 
 Watcher:
 arguments: watched,true,false,
 caller: null
 callee: watcher
+Child:
+arguments: 
+caller: watcher
+callee: func
 
 Broadcast:
 arguments: 
 caller: null
 callee: broadcast
-
-Calling from inside a function
-
-Check
-
-CallFunction
-arguments: 
-caller: check
-callee: func
-
-CallMethod
-arguments: 
-caller: check
-callee: func
-
-Call:
+Child:
 arguments: 
-caller: check
+caller: broadcast
 callee: func
 
-Apply:
-arguments: 
-caller: check
-callee: func
-
-New:
-arguments: 
-caller: check
-callee: func
-
-Sort:
-arguments: a,
-caller: check
-callee: func
-
-Prop set:
-arguments: 2
-caller: check
-callee: prop_set
-
-Prop get:
-arguments: 
-caller: check
-callee: prop_get
-
-Watcher:
-arguments: watched,,false,
-caller: check
-callee: watcher
-
-Broadcast:
-arguments: 
-caller: check
-callee: broadcast
-
 Timeout:
 arguments: 
 caller: null
 callee: timeout
+Child:
+arguments: 
+caller: timeout
+callee: func
diff --git a/test/trace/arguments-7.swf b/test/trace/arguments-7.swf
index 42fbf87..ec2528d 100644
Binary files a/test/trace/arguments-7.swf and b/test/trace/arguments-7.swf differ
diff --git a/test/trace/arguments-7.swf.trace b/test/trace/arguments-7.swf.trace
index e681495..dbcd38e 100644
--- a/test/trace/arguments-7.swf.trace
+++ b/test/trace/arguments-7.swf.trace
@@ -2,114 +2,92 @@ Global:
 arguments: undefined
 caller: undefined
 callee: undefined
-
-Calling from outside of function
-
-CallFunction
+Child CallFunction:
 arguments: 
 caller: null
 callee: func
-
-CallMethod
+Child CallMethod:
 arguments: 
 caller: null
 callee: func
 
-Call:
+Method:
 arguments: 
 caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
 callee: func
 
-Apply:
+Call:
 arguments: 
 caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
 callee: func
 
-New:
+Apply:
 arguments: 
 caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
 callee: func
 
 Sort:
 arguments: a,undefined
 caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
 callee: func
 
 Prop set:
-arguments: 2
+arguments: a,undefined
 caller: null
 callee: prop_set
+Child:
+arguments: 
+caller: prop_set
+callee: func
 
 Prop get:
 arguments: 
 caller: null
 callee: prop_get
+Child:
+arguments: 
+caller: prop_get
+callee: func
 
 Watcher:
 arguments: watched,true,false,undefined
 caller: null
 callee: watcher
+Child:
+arguments: 
+caller: watcher
+callee: func
 
 Broadcast:
 arguments: 
 caller: null
 callee: broadcast
-
-Calling from inside a function
-
-Check
-
-CallFunction
-arguments: 
-caller: check
-callee: func
-
-CallMethod
-arguments: 
-caller: check
-callee: func
-
-Call:
+Child:
 arguments: 
-caller: check
+caller: broadcast
 callee: func
 
-Apply:
-arguments: 
-caller: check
-callee: func
-
-New:
-arguments: 
-caller: check
-callee: func
-
-Sort:
-arguments: a,undefined
-caller: check
-callee: func
-
-Prop set:
-arguments: 2
-caller: check
-callee: prop_set
-
-Prop get:
-arguments: 
-caller: check
-callee: prop_get
-
-Watcher:
-arguments: watched,undefined,false,undefined
-caller: check
-callee: watcher
-
-Broadcast:
-arguments: 
-caller: check
-callee: broadcast
-
 Timeout:
 arguments: 
 caller: null
 callee: timeout
+Child:
+arguments: 
+caller: timeout
+callee: func
diff --git a/test/trace/arguments-8.swf b/test/trace/arguments-8.swf
index 3dc3637..08c8d36 100644
Binary files a/test/trace/arguments-8.swf and b/test/trace/arguments-8.swf differ
diff --git a/test/trace/arguments-8.swf.trace b/test/trace/arguments-8.swf.trace
index e681495..dbcd38e 100644
--- a/test/trace/arguments-8.swf.trace
+++ b/test/trace/arguments-8.swf.trace
@@ -2,114 +2,92 @@ Global:
 arguments: undefined
 caller: undefined
 callee: undefined
-
-Calling from outside of function
-
-CallFunction
+Child CallFunction:
 arguments: 
 caller: null
 callee: func
-
-CallMethod
+Child CallMethod:
 arguments: 
 caller: null
 callee: func
 
-Call:
+Method:
 arguments: 
 caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
 callee: func
 
-Apply:
+Call:
 arguments: 
 caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
 callee: func
 
-New:
+Apply:
 arguments: 
 caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
 callee: func
 
 Sort:
 arguments: a,undefined
 caller: null
+callee: func_and_child
+Child:
+arguments: 
+caller: func_and_child
 callee: func
 
 Prop set:
-arguments: 2
+arguments: a,undefined
 caller: null
 callee: prop_set
+Child:
+arguments: 
+caller: prop_set
+callee: func
 
 Prop get:
 arguments: 
 caller: null
 callee: prop_get
+Child:
+arguments: 
+caller: prop_get
+callee: func
 
 Watcher:
 arguments: watched,true,false,undefined
 caller: null
 callee: watcher
+Child:
+arguments: 
+caller: watcher
+callee: func
 
 Broadcast:
 arguments: 
 caller: null
 callee: broadcast
-
-Calling from inside a function
-
-Check
-
-CallFunction
-arguments: 
-caller: check
-callee: func
-
-CallMethod
-arguments: 
-caller: check
-callee: func
-
-Call:
+Child:
 arguments: 
-caller: check
+caller: broadcast
 callee: func
 
-Apply:
-arguments: 
-caller: check
-callee: func
-
-New:
-arguments: 
-caller: check
-callee: func
-
-Sort:
-arguments: a,undefined
-caller: check
-callee: func
-
-Prop set:
-arguments: 2
-caller: check
-callee: prop_set
-
-Prop get:
-arguments: 
-caller: check
-callee: prop_get
-
-Watcher:
-arguments: watched,undefined,false,undefined
-caller: check
-callee: watcher
-
-Broadcast:
-arguments: 
-caller: check
-callee: broadcast
-
 Timeout:
 arguments: 
 caller: null
 callee: timeout
+Child:
+arguments: 
+caller: timeout
+callee: func
diff --git a/test/trace/arguments.as b/test/trace/arguments.as
index 479013e..a7424dd 100644
--- a/test/trace/arguments.as
+++ b/test/trace/arguments.as
@@ -1,16 +1,59 @@
 // makeswf -v 7 -r 1 -o test-7.swf test.as
 
-trace ("Global:");
-trace ("arguments: " + arguments);
-trace ("caller: " + arguments.caller);
-trace ("callee: " + arguments.callee);
+var o = {};
+var tmp = {};
 
 function func () {
   trace ("arguments: " + arguments);
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
 }
-func.toString = function () { return "func"; };
+func.valueOf = func.toString = function () { return "func"; };
+
+function func_and_child () {
+  trace ("arguments: " + arguments);
+  trace ("caller: " + arguments.caller);
+  trace ("callee: " + arguments.callee);
+  trace ("Child:");
+  func ();
+}
+func_and_child.valueOf = func_and_child.toString =
+  function () { return "func_and_child"; };
+
+
+trace ("Global:");
+trace ("arguments: " + arguments);
+trace ("caller: " + arguments.caller);
+trace ("callee: " + arguments.callee);
+trace ("Child CallFunction:");
+func ();
+trace ("Child CallMethod:");
+o.func = func;
+o.func ();
+
+
+trace ("");
+trace ("Method:");
+o.func_and_child = func_and_child;
+o.func_and_child ();
+
+
+trace ("");
+trace ("Call:");
+func_and_child.call ();
+
+
+trace ("");
+trace ("Apply:");
+func_and_child.apply ();
+
+
+trace ("");
+trace ("Sort:");
+tmp = new Array (2);
+tmp[0] = "a";
+tmp.sort (func_and_child);
+
 
 function prop_get () {
   trace ("");
@@ -18,8 +61,10 @@ function prop_get () {
   trace ("arguments: " + arguments);
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
+  trace ("Child:");
+  func ();
 }
-prop_get.toString = function () { return "prop_get"; };
+prop_get.valueOf = prop_get.toString = function () { return "prop_get"; };
 
 function prop_set () {
   trace ("");
@@ -27,8 +72,16 @@ function prop_set () {
   trace ("arguments: " + arguments);
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
+  trace ("Child:");
+  func ();
 }
-prop_set.toString = function () { return "prop_set"; };
+prop_set.valueOf = prop_set.toString = function () { return "prop_set"; };
+
+o.addProperty ("prop", prop_get, prop_set);
+
+o.prop = tmp;
+tmp = o.prop;
+
 
 function watcher () {
   trace ("");
@@ -36,14 +89,15 @@ function watcher () {
   trace ("arguments: " + arguments);
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
+  trace ("Child:");
+  func ();
 }
-watcher.toString = function () { return "watcher"; };
+watcher.valueOf = watcher.toString = function () { return "watcher"; };
 
-var o = {};
-o.func = func;
-o.addProperty ("prop", prop_get, prop_set);
 o.watched = true;
 o.watch ("watched", watcher);
+o.watched = false;
+
 
 var emitter = new Object ();
 AsBroadcaster.initialize (emitter);
@@ -54,97 +108,26 @@ emitter._listeners[0].broadcast = function () {
   trace ("arguments: " + arguments);
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
+  trace ("Child:");
+  func ();
 };
+emitter._listeners[0].broadcast.valueOf = function () { return "broadcast"; };
 emitter._listeners[0].broadcast.toString = function () { return "broadcast"; };
 
+emitter.broadcastMessage ("broadcast");
+
+
 function timeout () {
   trace ("");
   trace ("Timeout:");
   trace ("arguments: " + arguments);
   trace ("caller: " + arguments.caller);
   trace ("callee: " + arguments.callee);
-
-  loadMovie ("FSCommand:quit", "");
-}
-timeout.toString = function () { return "timeout"; };
-
-trace ("");
-trace ("Calling from outside of function");
-
-trace ("");
-trace ("CallFunction");
-func ();
-
-trace ("");
-trace ("CallMethod");
-o.func ();
-
-trace ("");
-trace ("Call:");
-func.call ();
-
-trace ("");
-trace ("Apply:");
-func.apply ();
-
-trace ("");
-trace ("New:");
-var a = new func ();
-
-trace ("");
-trace ("Sort:");
-a = new Array (2);
-a[0] = "a";
-a.sort (func);
-
-o.prop = 2;
-a = o.prop;
-
-o.watched = false;
-
-emitter.broadcastMessage ("broadcast");
-
-function check () {
-  trace ("");
-  trace ("CallFunction");
+  trace ("Child:");
   func ();
 
-  trace ("");
-  trace ("CallMethod");
-  o.func ();
-
-  trace ("");
-  trace ("Call:");
-  func.call ();
-
-  trace ("");
-  trace ("Apply:");
-  func.apply ();
-
-  trace ("");
-  trace ("New:");
-  var a = new func ();
-
-  trace ("");
-  trace ("Sort:");
-  a = new Array (2);
-  a[0] = "a";
-  a.sort (func);
-
-  o.prop = 2;
-  a = o.prop;
-
-  o.watched = false;
-
-  emitter.broadcastMessage ("broadcast");
-
-  setTimeout (timeout, 0);
+  loadMovie ("FSCommand:quit", "");
 }
-check.toString = function () { return "check"; };
+timeout.valueOf = timeout.toString = function () { return "timeout"; };
 
-trace ("");
-trace ("Calling from inside a function");
-
-trace ("");
-trace ("Check");
-check ();
+setTimeout (timeout, 0);
commit 514e96065d3cec017e19ad5279b4dfcd60e173c7
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Thu Nov 15 20:05:14 2007 +0200

    Rework arguments.caller code, it wasn't working correctly

diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c
index 3c6cde5..ed531a7 100644
--- a/libswfdec/swfdec_as_array.c
+++ b/libswfdec/swfdec_as_array.c
@@ -1228,6 +1228,9 @@ swfdec_as_array_do_sort (SwfdecAsObject *object, gint32 options,
   fdata.compare_custom_func = custom_compare_func;
   fdata.fields = fields;
 
+  // don't mark this function as the caller of custom sort function
+  object->context->frame->caller = FALSE;
+
   // generate fdata.order which points to the values
   if (!swfdec_as_object_foreach (object, swfdec_as_array_foreach_sort_populate,
 	&fdata))
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 26287bc..5f0a40d 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -378,6 +378,7 @@ swfdec_as_frame_init (SwfdecAsFrame *frame)
   frame->function_name = "unnamed";
   frame->blocks = g_array_new (FALSE, FALSE, sizeof (SwfdecAsFrameBlock));
   frame->block_end = (gpointer) -1;
+  frame->caller = TRUE;
 }
 
 static void
@@ -688,6 +689,7 @@ swfdec_as_frame_preload (SwfdecAsFrame *frame)
 
   /* create arguments and super object if necessary */
   if ((script->flags & (SWFDEC_SCRIPT_PRELOAD_ARGS | SWFDEC_SCRIPT_SUPPRESS_ARGS)) != SWFDEC_SCRIPT_SUPPRESS_ARGS) {
+    SwfdecAsFrame *next;
     args = swfdec_as_array_new (context);
     if (!args)
       goto out;
@@ -696,15 +698,19 @@ swfdec_as_frame_preload (SwfdecAsFrame *frame)
       swfdec_as_array_push (SWFDEC_AS_ARRAY (args), cur);
     }
 
-    if (frame->caller != NULL) {
-      SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (frame->caller));
+    next = frame->next;
+    while (next && next->caller == FALSE) {
+      next = next->next;
+    }
+    if (next != NULL && next->function != NULL) {
+      SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (next->function));
     } else {
       SWFDEC_AS_VALUE_SET_NULL (&val);
     }
     swfdec_as_object_set_variable (args, SWFDEC_AS_STR_caller, &val);
 
-    if (frame->callee != NULL) {
-      SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (frame->callee));
+    if (frame->function != NULL) {
+      SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (frame->function));
     } else {
       SWFDEC_AS_VALUE_SET_NULL (&val);
     }
diff --git a/libswfdec/swfdec_as_frame_internal.h b/libswfdec/swfdec_as_frame_internal.h
index 7c4f3ac..44a87af 100644
--- a/libswfdec/swfdec_as_frame_internal.h
+++ b/libswfdec/swfdec_as_frame_internal.h
@@ -33,6 +33,7 @@ struct _SwfdecAsFrame {
 
   SwfdecAsFrame *	next;		/* next frame (FIXME: keep a list in the context instead?) */
   SwfdecAsFunction *	function;	/* function we're executing or NULL if toplevel */
+  gboolean		caller;		/* this function can be used as arguments.caller */
   SwfdecAsObject *	thisp;		/* this object in current frame or NULL if none */
   SwfdecAsObject *	super;		/* super object in current frame or NULL if none */
   gboolean		construct;	/* TRUE if this is the constructor for thisp */
@@ -40,9 +41,6 @@ struct _SwfdecAsFrame {
   guint			argc;		/* number of arguments */
   const SwfdecAsValue *	argv;		/* arguments or %NULL if taken from stack */
   SwfdecSecurity *	security;	/* security for this frame or %NULL if not allowed to call */
-  SwfdecAsFunction *	caller;		/* the function that made the call or %NULL */
-  SwfdecAsFunction *	callee;		/* the function being called or %NULL */
-  gboolean		update_caller;	/* whether callee should be used as a caller for called functions */
   /* debugging */
   const char *		function_name;	/* name of function */
   /* script execution */
diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index 0f0d3b5..a8f0d66 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -103,9 +103,7 @@ swfdec_as_function_call_no_preload (SwfdecAsFunction *function,
     SwfdecAsObject *thisp, guint n_args, const SwfdecAsValue *args, 
     SwfdecAsValue *return_value)
 {
-  SwfdecAsContext *context;
   SwfdecAsFrame *frame;
-  SwfdecAsFunction *caller;
   SwfdecAsFunctionClass *klass;
 
   g_return_val_if_fail (SWFDEC_IS_AS_FUNCTION (function), NULL);
@@ -115,14 +113,6 @@ swfdec_as_function_call_no_preload (SwfdecAsFunction *function,
   if (return_value)
     SWFDEC_AS_VALUE_SET_UNDEFINED (return_value);
 
-  context = SWFDEC_AS_OBJECT (function)->context;
-  if (context->frame != NULL) {
-    caller = (context->frame->update_caller ? context->frame->callee :
-	context->frame->caller);
-  } else {
-    caller = NULL;
-  }
-
   klass = SWFDEC_AS_FUNCTION_GET_CLASS (function);
   g_assert (klass->call);
   frame = klass->call (function);
@@ -138,8 +128,6 @@ swfdec_as_function_call_no_preload (SwfdecAsFunction *function,
     swfdec_as_frame_set_this (frame, swfdec_as_object_resolve (thisp));
   }
   frame->is_local = TRUE;
-  frame->caller = caller;
-  frame->callee = function;
   frame->argc = n_args;
   frame->argv = args;
   frame->return_value = return_value;
@@ -203,6 +191,7 @@ swfdec_as_function_do_call (SwfdecAsContext *cx, SwfdecAsObject *object,
     argc--;
     argv++;
   }
+  cx->frame->caller = FALSE; // don't mark this function as the caller
   swfdec_as_function_call (fun, thisp, argc, argv, ret);
   swfdec_as_context_run (cx);
 }
@@ -250,6 +239,7 @@ swfdec_as_function_apply (SwfdecAsContext *cx, SwfdecAsObject *object,
     }
   }
 
+  cx->frame->caller = FALSE; // don't mark this function as the caller
   swfdec_as_function_call (fun, thisp, length, argv_pass, ret);
   swfdec_as_context_run (cx);
 
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index ab6b41c..7d6686f 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -865,7 +865,6 @@ swfdec_action_call_function (SwfdecAsContext *cx, guint action, const guint8 *da
   frame = swfdec_action_call (cx, n_args);
   if (frame) {
     swfdec_as_frame_preload (frame);
-    frame->update_caller = TRUE;
   } else {
     SWFDEC_WARNING ("no function named %s", name);
   }
diff --git a/libswfdec/swfdec_asbroadcaster.c b/libswfdec/swfdec_asbroadcaster.c
index 7d26d64..61bb6d0 100644
--- a/libswfdec/swfdec_asbroadcaster.c
+++ b/libswfdec/swfdec_asbroadcaster.c
@@ -24,6 +24,8 @@
 #include "swfdec_as_internal.h"
 #include "swfdec_as_object.h"
 #include "swfdec_as_strings.h"
+#include "swfdec_as_context.h"
+#include "swfdec_as_frame_internal.h"
 #include "swfdec_debug.h"
 
 /*** AS CODE ***/
@@ -70,6 +72,8 @@ broadcastMessage (SwfdecAsContext *cx, SwfdecAsObject *object,
   }
   if (list == NULL)
     return;
+
+  cx->frame->caller = FALSE; // don't mark this function as the caller
   list = g_slist_reverse (list);
   for (walk = list; walk; walk = walk->next) {
     swfdec_as_object_call (walk->data, name, argc, argv, &val);


More information about the Swfdec mailing list