[Swfdec] Branch 'as' - 7 commits - libswfdec/swfdec_as_context.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_super.c libswfdec/swfdec_as_super.h libswfdec/swfdec_as_with.c test/trace
Benjamin Otte
company at kemper.freedesktop.org
Sat Jul 7 09:30:16 PDT 2007
libswfdec/swfdec_as_context.c | 7 +-
libswfdec/swfdec_as_interpret.c | 35 ++++++-----
libswfdec/swfdec_as_object.c | 12 +++
libswfdec/swfdec_as_object.h | 5 -
libswfdec/swfdec_as_super.c | 46 +++++++++++++-
libswfdec/swfdec_as_super.h | 2
libswfdec/swfdec_as_with.c | 2
test/trace/Makefile.am | 32 ++++++++++
test/trace/extends-constructors-6.swf |binary
test/trace/extends-constructors-6.swf.trace | 8 ++
test/trace/extends-constructors-7.swf |binary
test/trace/extends-constructors-7.swf.trace | 8 ++
test/trace/extends-constructors-8.swf |binary
test/trace/extends-constructors-8.swf.trace | 8 ++
test/trace/extends-constructors.as | 72 ++++++++++++++++++++++
test/trace/super-different-5.swf |binary
test/trace/super-different-5.swf.trace | 4 +
test/trace/super-different-6.swf |binary
test/trace/super-different-6.swf.trace | 12 +++
test/trace/super-different-7.swf |binary
test/trace/super-different-7.swf.trace | 12 +++
test/trace/super-different-8.swf |binary
test/trace/super-different-8.swf.trace | 12 +++
test/trace/super-different.as | 66 ++++++++++++++++++++
test/trace/super-missing-5.swf |binary
test/trace/super-missing-5.swf.trace | 3
test/trace/super-missing-6.swf |binary
test/trace/super-missing-6.swf.trace | 9 ++
test/trace/super-missing-7.swf |binary
test/trace/super-missing-7.swf.trace | 8 ++
test/trace/super-missing-8.swf |binary
test/trace/super-missing-8.swf.trace | 8 ++
test/trace/super-missing.as | 52 ++++++++++++++++
test/trace/super-reference-6.swf |binary
test/trace/super-reference-6.swf.trace | 25 +++++++
test/trace/super-reference-7.swf |binary
test/trace/super-reference-7.swf.trace | 24 +++++++
test/trace/super-reference-8.swf |binary
test/trace/super-reference-8.swf.trace | 24 +++++++
test/trace/super-reference.as | 89 ++++++++++++++++++++++++++++
40 files changed, 562 insertions(+), 23 deletions(-)
New commits:
diff-tree aab61502175bd018e7de1c01b8ef86b909d932a0 (from a510f23c72c980303c86f869023237bc593fdfe0)
Author: Benjamin Otte <otte at gnome.org>
Date: Sat Jul 7 17:30:17 2007 +0100
add a test for not overwritten functions in subclasses
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index d72d5e2..695cbba 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -779,6 +779,15 @@ EXTRA_DIST = \
super-different-7.swf.trace \
super-different-8.swf \
super-different-8.swf.trace \
+ super-missing.as \
+ super-missing-5.swf \
+ super-missing-5.swf.trace \
+ super-missing-6.swf \
+ super-missing-6.swf.trace \
+ super-missing-7.swf \
+ super-missing-7.swf.trace \
+ super-missing-8.swf \
+ super-missing-8.swf.trace \
super-reference.as \
super-reference-6.swf \
super-reference-6.swf.trace \
diff --git a/test/trace/super-missing-5.swf b/test/trace/super-missing-5.swf
new file mode 100644
index 0000000..7d6b079
Binary files /dev/null and b/test/trace/super-missing-5.swf differ
diff --git a/test/trace/super-missing-5.swf.trace b/test/trace/super-missing-5.swf.trace
new file mode 100644
index 0000000..3db6946
--- /dev/null
+++ b/test/trace/super-missing-5.swf.trace
@@ -0,0 +1,3 @@
+Check how functions that aren't overwritten are handled when called via super
+4
+foo: 4
diff --git a/test/trace/super-missing-6.swf b/test/trace/super-missing-6.swf
new file mode 100644
index 0000000..8e4d85d
Binary files /dev/null and b/test/trace/super-missing-6.swf differ
diff --git a/test/trace/super-missing-6.swf.trace b/test/trace/super-missing-6.swf.trace
new file mode 100644
index 0000000..1f60a12
--- /dev/null
+++ b/test/trace/super-missing-6.swf.trace
@@ -0,0 +1,9 @@
+Check how functions that aren't overwritten are handled when called via super
+1
+2
+3
+4
+foo: 1
+foo: 1
+foo: 1
+foo: 4
diff --git a/test/trace/super-missing-7.swf b/test/trace/super-missing-7.swf
new file mode 100644
index 0000000..6a1bbfd
Binary files /dev/null and b/test/trace/super-missing-7.swf differ
diff --git a/test/trace/super-missing-7.swf.trace b/test/trace/super-missing-7.swf.trace
new file mode 100644
index 0000000..f72f2f9
--- /dev/null
+++ b/test/trace/super-missing-7.swf.trace
@@ -0,0 +1,8 @@
+Check how functions that aren't overwritten are handled when called via super
+1
+2
+3
+4
+foo: 1
+foo: 1
+foo: 4
diff --git a/test/trace/super-missing-8.swf b/test/trace/super-missing-8.swf
new file mode 100644
index 0000000..4172ebe
Binary files /dev/null and b/test/trace/super-missing-8.swf differ
diff --git a/test/trace/super-missing-8.swf.trace b/test/trace/super-missing-8.swf.trace
new file mode 100644
index 0000000..f72f2f9
--- /dev/null
+++ b/test/trace/super-missing-8.swf.trace
@@ -0,0 +1,8 @@
+Check how functions that aren't overwritten are handled when called via super
+1
+2
+3
+4
+foo: 1
+foo: 1
+foo: 4
diff --git a/test/trace/super-missing.as b/test/trace/super-missing.as
new file mode 100644
index 0000000..2bd6fe7
--- /dev/null
+++ b/test/trace/super-missing.as
@@ -0,0 +1,52 @@
+// makeswf -v 7 -s 200x150 -r 1 -o super-missing.swf super-missing.as
+
+trace ("Check how functions that aren't overwritten are handled when called via super");
+
+function One () {
+ trace (1);
+};
+function Two () {
+ super ();
+ trace (2);
+};
+function Three () {
+ super ();
+ trace (3);
+};
+function Four () {
+ super ();
+ trace (4);
+};
+asm {
+ push "Two"
+ getvariable
+ push "One"
+ getvariable
+ extends
+};
+asm {
+ push "Three"
+ getvariable
+ push "Two"
+ getvariable
+ extends
+};
+asm {
+ push "Four"
+ getvariable
+ push "Three"
+ getvariable
+ extends
+};
+One.prototype.foo = function () {
+ super.foo ();
+ trace ("foo: 1");
+};
+Four.prototype.foo = function () {
+ super.foo ();
+ trace ("foo: 4");
+};
+x = new Four ();
+x.foo ();
+
+loadMovie ("FSCommand:quit", "");
diff-tree a510f23c72c980303c86f869023237bc593fdfe0 (from cb0a5b3d2714123e50f45869100e4665c4100379)
Author: Benjamin Otte <otte at gnome.org>
Date: Sat Jul 7 17:28:02 2007 +0100
ad a test for calling different named functions via super
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 9474502..d72d5e2 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -770,6 +770,15 @@ EXTRA_DIST = \
super-calls-7.swf.trace \
super-calls-8.swf \
super-calls-8.swf.trace \
+ super-different.as \
+ super-different-5.swf \
+ super-different-5.swf.trace \
+ super-different-6.swf \
+ super-different-6.swf.trace \
+ super-different-7.swf \
+ super-different-7.swf.trace \
+ super-different-8.swf \
+ super-different-8.swf.trace \
super-reference.as \
super-reference-6.swf \
super-reference-6.swf.trace \
diff --git a/test/trace/super-different-5.swf b/test/trace/super-different-5.swf
new file mode 100644
index 0000000..3cf24ad
Binary files /dev/null and b/test/trace/super-different-5.swf differ
diff --git a/test/trace/super-different-5.swf.trace b/test/trace/super-different-5.swf.trace
new file mode 100644
index 0000000..c89f1d6
--- /dev/null
+++ b/test/trace/super-different-5.swf.trace
@@ -0,0 +1,4 @@
+Check calls to differently named functions on super
+4
+foo: x
+bla: x
diff --git a/test/trace/super-different-6.swf b/test/trace/super-different-6.swf
new file mode 100644
index 0000000..323d467
Binary files /dev/null and b/test/trace/super-different-6.swf differ
diff --git a/test/trace/super-different-6.swf.trace b/test/trace/super-different-6.swf.trace
new file mode 100644
index 0000000..f2db9cf
--- /dev/null
+++ b/test/trace/super-different-6.swf.trace
@@ -0,0 +1,12 @@
+Check calls to differently named functions on super
+1
+2
+3
+4
+bla: 1
+foo: 2
+bla: 3
+foo: x
+bla: 1
+foo: 2
+bla: x
diff --git a/test/trace/super-different-7.swf b/test/trace/super-different-7.swf
new file mode 100644
index 0000000..a3e5912
Binary files /dev/null and b/test/trace/super-different-7.swf differ
diff --git a/test/trace/super-different-7.swf.trace b/test/trace/super-different-7.swf.trace
new file mode 100644
index 0000000..f2db9cf
--- /dev/null
+++ b/test/trace/super-different-7.swf.trace
@@ -0,0 +1,12 @@
+Check calls to differently named functions on super
+1
+2
+3
+4
+bla: 1
+foo: 2
+bla: 3
+foo: x
+bla: 1
+foo: 2
+bla: x
diff --git a/test/trace/super-different-8.swf b/test/trace/super-different-8.swf
new file mode 100644
index 0000000..508e675
Binary files /dev/null and b/test/trace/super-different-8.swf differ
diff --git a/test/trace/super-different-8.swf.trace b/test/trace/super-different-8.swf.trace
new file mode 100644
index 0000000..f2db9cf
--- /dev/null
+++ b/test/trace/super-different-8.swf.trace
@@ -0,0 +1,12 @@
+Check calls to differently named functions on super
+1
+2
+3
+4
+bla: 1
+foo: 2
+bla: 3
+foo: x
+bla: 1
+foo: 2
+bla: x
diff --git a/test/trace/super-different.as b/test/trace/super-different.as
new file mode 100644
index 0000000..155d1fd
--- /dev/null
+++ b/test/trace/super-different.as
@@ -0,0 +1,66 @@
+// makeswf -v 7 -s 200x150 -r 1 -o super-different.swf super-different.as
+
+trace ("Check calls to differently named functions on super");
+function One () {
+ trace (1);
+};
+function Two () {
+ super ();
+ trace (2);
+};
+function Three () {
+ super ();
+ trace (3);
+};
+function Four () {
+ super ();
+ trace (4);
+};
+asm {
+ push "Two"
+ getvariable
+ push "One"
+ getvariable
+ extends
+};
+asm {
+ push "Three"
+ getvariable
+ push "Two"
+ getvariable
+ extends
+};
+asm {
+ push "Four"
+ getvariable
+ push "Three"
+ getvariable
+ extends
+};
+One.prototype.foo = function () {
+ trace ("foo: 1");
+};
+One.prototype.bla = function () {
+ trace ("bla: 1");
+};
+Two.prototype.foo = function () {
+ super.bla ();
+ trace ("foo: 2");
+};
+Three.prototype.bla = function () {
+ super.foo ();
+ trace ("bla: 3");
+};
+x = new Four ();
+x.foo = function () {
+ super.bla ();
+ trace ("foo: x");
+};
+x.bla = function () {
+ super.foo ();
+ trace ("bla: x");
+};
+x.foo ();
+x.bla ();
+
+loadMovie ("FSCommand:quit", "");
diff-tree cb0a5b3d2714123e50f45869100e4665c4100379 (from 96c3f00fcd2a7333f82399b370de89f2e2fc4e48)
Author: Benjamin Otte <otte at gnome.org>
Date: Sat Jul 7 17:27:04 2007 +0100
add a test to see which prototype is referenced by super
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 4115b34..9474502 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -770,6 +770,13 @@ EXTRA_DIST = \
super-calls-7.swf.trace \
super-calls-8.swf \
super-calls-8.swf.trace \
+ super-reference.as \
+ super-reference-6.swf \
+ super-reference-6.swf.trace \
+ super-reference-7.swf \
+ super-reference-7.swf.trace \
+ super-reference-8.swf \
+ super-reference-8.swf.trace \
targetpath.as \
targetpath-5.swf \
targetpath-5.swf.trace \
diff --git a/test/trace/super-reference-6.swf b/test/trace/super-reference-6.swf
new file mode 100644
index 0000000..17aadb4
Binary files /dev/null and b/test/trace/super-reference-6.swf differ
diff --git a/test/trace/super-reference-6.swf.trace b/test/trace/super-reference-6.swf.trace
new file mode 100644
index 0000000..bd485ee
--- /dev/null
+++ b/test/trace/super-reference-6.swf.trace
@@ -0,0 +1,25 @@
+Check which object super refers to
+1
+2
+3
+4
+foo: 1
+foo: 2
+foo: 3
+bla
+3
+foo: 1
+foo: 2
+foo: 3
+bla
+3
+foo: 1
+foo: 2
+foo: 3
+foo: 5
+3
+foo: 1
+foo: 2
+foo: 3
+foo: 5
+3
diff --git a/test/trace/super-reference-7.swf b/test/trace/super-reference-7.swf
new file mode 100644
index 0000000..40c5ed9
Binary files /dev/null and b/test/trace/super-reference-7.swf differ
diff --git a/test/trace/super-reference-7.swf.trace b/test/trace/super-reference-7.swf.trace
new file mode 100644
index 0000000..b7c101e
--- /dev/null
+++ b/test/trace/super-reference-7.swf.trace
@@ -0,0 +1,24 @@
+Check which object super refers to
+1
+2
+3
+4
+foo: 1
+foo: 2
+bla
+2
+foo: 1
+foo: 2
+foo: 3
+bla
+3
+foo: 1
+foo: 2
+foo: 3
+foo: 5
+3
+foo: 1
+foo: 2
+foo: 3
+foo: 5
+3
diff --git a/test/trace/super-reference-8.swf b/test/trace/super-reference-8.swf
new file mode 100644
index 0000000..f7dcd95
Binary files /dev/null and b/test/trace/super-reference-8.swf differ
diff --git a/test/trace/super-reference-8.swf.trace b/test/trace/super-reference-8.swf.trace
new file mode 100644
index 0000000..b7c101e
--- /dev/null
+++ b/test/trace/super-reference-8.swf.trace
@@ -0,0 +1,24 @@
+Check which object super refers to
+1
+2
+3
+4
+foo: 1
+foo: 2
+bla
+2
+foo: 1
+foo: 2
+foo: 3
+bla
+3
+foo: 1
+foo: 2
+foo: 3
+foo: 5
+3
+foo: 1
+foo: 2
+foo: 3
+foo: 5
+3
diff --git a/test/trace/super-reference.as b/test/trace/super-reference.as
new file mode 100644
index 0000000..fef6fe6
--- /dev/null
+++ b/test/trace/super-reference.as
@@ -0,0 +1,89 @@
+// makeswf -v 7 -s 200x150 -r 1 -o super-reference.swf super-reference.as
+
+trace ("Check which object super refers to");
+
+function One () {
+ trace (1);
+};
+function Two () {
+ super ();
+ trace (2);
+};
+function Three () {
+ super ();
+ trace (3);
+};
+function Four () {
+ super ();
+ trace (4);
+};
+asm {
+ push "Two"
+ getvariable
+ push "One"
+ getvariable
+ extends
+};
+asm {
+ push "Three"
+ getvariable
+ push "Two"
+ getvariable
+ extends
+};
+asm {
+ push "Four"
+ getvariable
+ push "Three"
+ getvariable
+ extends
+};
+function check (x) {
+ if (x.foo === One.prototype.foo)
+ trace (1);
+ else if (x.foo === Two.prototype.foo)
+ trace (2);
+ else if (x.foo === Three.prototype.foo)
+ trace (3);
+ else if (x.foo === Four.prototype.foo)
+ trace (4);
+ else
+ trace ("5+");
+};
+One.prototype.foo = function () {
+ trace ("foo: 1");
+};
+Two.prototype.foo = function () {
+ super.foo ();
+ trace ("foo: 2");
+};
+Three.prototype.foo = function () {
+ super.foo ();
+ trace ("foo: 3");
+};
+Four.prototype.foo = function () {
+ super.foo ();
+ trace ("foo: 4");
+};
+Two.prototype.bla = function () {
+ super.foo ();
+ trace ("blabla");
+ check (super);
+};
+Three.prototype.bla = function () {
+ super.foo ();
+ trace ("bla");
+ check (super);
+};
+x = new Four ();
+x.foo = function () {
+ super.foo ();
+ trace ("foo: 5");
+ check (super);
+};
+x.bla ();
+x.bla.call (x);
+x.foo ();
+x.foo.call (x);
+
+loadMovie ("FSCommand:quit", "");
diff-tree 96c3f00fcd2a7333f82399b370de89f2e2fc4e48 (from a2c9ed6d7a22fa26d5581e9e42e31ffb0b82c3d4)
Author: Benjamin Otte <otte at gnome.org>
Date: Sat Jul 7 17:25:27 2007 +0100
add a test that checks the constructor properties on prototypes after ActionExtends
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index f537b21..4115b34 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -229,6 +229,13 @@ EXTRA_DIST = \
export-case-6.swf.trace \
export-case-7.swf \
export-case-7.swf.trace \
+ extends-constructors.as \
+ extends-constructors-6.swf \
+ extends-constructors-6.swf.trace \
+ extends-constructors-7.swf \
+ extends-constructors-7.swf.trace \
+ extends-constructors-8.swf \
+ extends-constructors-8.swf.trace \
extends-simple.swf \
extends-simple.swf.trace \
extends-super.swf \
diff --git a/test/trace/extends-constructors-6.swf b/test/trace/extends-constructors-6.swf
new file mode 100644
index 0000000..b035036
Binary files /dev/null and b/test/trace/extends-constructors-6.swf differ
diff --git a/test/trace/extends-constructors-6.swf.trace b/test/trace/extends-constructors-6.swf.trace
new file mode 100644
index 0000000..cf826c8
--- /dev/null
+++ b/test/trace/extends-constructors-6.swf.trace
@@ -0,0 +1,8 @@
+One
+undefined
+One
+One
+One
+Two
+One
+Three
diff --git a/test/trace/extends-constructors-7.swf b/test/trace/extends-constructors-7.swf
new file mode 100644
index 0000000..5b80340
Binary files /dev/null and b/test/trace/extends-constructors-7.swf differ
diff --git a/test/trace/extends-constructors-7.swf.trace b/test/trace/extends-constructors-7.swf.trace
new file mode 100644
index 0000000..cf826c8
--- /dev/null
+++ b/test/trace/extends-constructors-7.swf.trace
@@ -0,0 +1,8 @@
+One
+undefined
+One
+One
+One
+Two
+One
+Three
diff --git a/test/trace/extends-constructors-8.swf b/test/trace/extends-constructors-8.swf
new file mode 100644
index 0000000..58d6abe
Binary files /dev/null and b/test/trace/extends-constructors-8.swf differ
diff --git a/test/trace/extends-constructors-8.swf.trace b/test/trace/extends-constructors-8.swf.trace
new file mode 100644
index 0000000..cf826c8
--- /dev/null
+++ b/test/trace/extends-constructors-8.swf.trace
@@ -0,0 +1,8 @@
+One
+undefined
+One
+One
+One
+Two
+One
+Three
diff --git a/test/trace/extends-constructors.as b/test/trace/extends-constructors.as
new file mode 100644
index 0000000..dc6e393
--- /dev/null
+++ b/test/trace/extends-constructors.as
@@ -0,0 +1,72 @@
+// makeswf -v 7 -s 200x150 -r 1 -o extends-constructors.swf extends-constructors.as
+
+function One () {
+ trace (1);
+};
+function Two () {
+ super ();
+ trace (2);
+};
+function Three () {
+ super ();
+ trace (3);
+};
+function Four () {
+ super ();
+ trace (4);
+};
+asm {
+ push "Two"
+ getvariable
+ push "One"
+ getvariable
+ extends
+};
+asm {
+ push "Three"
+ getvariable
+ push "Two"
+ getvariable
+ extends
+};
+asm {
+ push "Four"
+ getvariable
+ push "Three"
+ getvariable
+ extends
+};
+One.prototype.foo = function () {
+ trace (super);
+ trace ("foo: 1");
+};
+Two.prototype.foo = function () {
+ super.foo ();
+ trace ("foo: 2");
+};
+Four.prototype.foo = function () {
+ super.foo ();
+ trace ("foo: 4");
+};
+function check_name (fun) {
+ if (fun === One)
+ trace ("One");
+ else if (fun === Two)
+ trace ("Two");
+ else if (fun === Three)
+ trace ("Three");
+ else if (fun === Four)
+ trace ("Four");
+ else
+ trace (fun);
+};
+check_name (One.prototype.constructor);
+check_name (One.prototype.__constructor__);
+check_name (Two.prototype.constructor);
+check_name (Two.prototype.__constructor__);
+check_name (Three.prototype.constructor);
+check_name (Three.prototype.__constructor__);
+check_name (Four.prototype.constructor);
+check_name (Four.prototype.__constructor__);
+
+loadMovie ("FSCommand:quit", "");
diff-tree a2c9ed6d7a22fa26d5581e9e42e31ffb0b82c3d4 (from f09bcc6abc2629a38f1524d647ec5ee1e6c2b612)
Author: Benjamin Otte <otte at gnome.org>
Date: Sat Jul 7 17:18:00 2007 +0100
skip unknown actions
This may be an interesting patch because Swfdec doesn't abort on weird code
anymore but just continues running. And it also keeps going for unknown
actions.
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 9257371..0d50224 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -680,10 +680,11 @@ start:
}
/* check action is valid */
if (spec->exec[version] == NULL) {
- SWFDEC_ERROR ("cannot interpret action %3u 0x%02X %s for version %u", action,
+ SWFDEC_WARNING ("cannot interpret action %3u 0x%02X %s for version %u, skipping it", action,
action, spec->name ? spec->name : "Unknown", script->version);
- /* FIXME: figure out what flash player does here */
- goto error;
+ frame->pc = pc = nextpc;
+ check_scope = TRUE;
+ continue;
}
if (spec->remove > 0) {
swfdec_as_stack_ensure_size (stack, spec->remove);
diff-tree f09bcc6abc2629a38f1524d647ec5ee1e6c2b612 (from d4d1998c7e04a7651d89a2c3fb56eb90ba3d474d)
Author: Benjamin Otte <otte at gnome.org>
Date: Sat Jul 7 17:14:29 2007 +0100
rewrite super handling
Super seems to be handled in a way stupid (and buggy) way. This seems to make
all the testcases (soon to be committed) work.
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 2cabb64..7ade8ca 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -560,7 +560,7 @@ swfdec_action_trace (SwfdecAsContext *cx
/* stack looks like this: [ function, this, arg1, arg2, ... ] */
/* stack must be at least 2 elements big */
static gboolean
-swfdec_action_call (SwfdecAsContext *cx, guint n_args, gboolean use_super)
+swfdec_action_call (SwfdecAsContext *cx, guint n_args)
{
SwfdecAsFunction *fun;
SwfdecAsObject *thisp;
@@ -592,11 +592,9 @@ swfdec_action_call (SwfdecAsContext *cx,
swfdec_as_stack_pop_n (frame->stack, n_args);
swfdec_as_function_call (fun, thisp, n_args, swfdec_as_stack_peek (frame->stack, 0),
swfdec_as_stack_peek (frame->stack, 1));
- if (use_super) {
- if (cx->frame->super && SWFDEC_AS_SUPER (frame->super)->object) {
- SWFDEC_LOG ("replacing super object on frame");
- SWFDEC_AS_SUPER (cx->frame->super)->object = SWFDEC_AS_SUPER (frame->super)->object->prototype;
- }
+ if (SWFDEC_IS_AS_SUPER (fun)) {
+ SWFDEC_LOG ("replacing super object on frame");
+ swfdec_as_super_replace (SWFDEC_AS_SUPER (fun), NULL);
}
return TRUE;
@@ -631,8 +629,7 @@ swfdec_action_call_function (SwfdecAsCon
SWFDEC_AS_VALUE_SET_NULL (thisp);
SWFDEC_AS_VALUE_SET_UNDEFINED (fun);
}
- if (!swfdec_action_call (cx, n_args, SWFDEC_AS_VALUE_IS_OBJECT (fun) &&
- SWFDEC_IS_AS_SUPER (SWFDEC_AS_VALUE_GET_OBJECT (fun)))) {
+ if (!swfdec_action_call (cx, n_args)) {
SWFDEC_ERROR ("no function named %s", name);
}
}
@@ -645,7 +642,6 @@ swfdec_action_call_method (SwfdecAsConte
SwfdecAsObject *obj;
guint n_args;
const char *name = NULL;
- gboolean use_super = FALSE;
swfdec_as_stack_ensure_size (frame->stack, 3);
obj = swfdec_as_value_to_object (cx, swfdec_as_stack_peek (frame->stack, 2));
@@ -656,8 +652,6 @@ swfdec_action_call_method (SwfdecAsConte
SWFDEC_AS_VALUE_SET_STRING (val, SWFDEC_AS_STR_EMPTY);
}
if (obj) {
- if (SWFDEC_IS_AS_SUPER (obj))
- use_super = TRUE;
if (SWFDEC_AS_VALUE_IS_STRING (val) &&
SWFDEC_AS_VALUE_GET_STRING (val) == SWFDEC_AS_STR_EMPTY) {
SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (frame->stack, 3));
@@ -674,7 +668,22 @@ swfdec_action_call_method (SwfdecAsConte
SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (frame->stack, 2));
}
swfdec_as_stack_pop (frame->stack);
- if (!swfdec_action_call (cx, n_args, use_super)) {
+ if (swfdec_action_call (cx, n_args)) {
+ /* setup super to point to the right prototype */
+ frame = cx->frame;
+ if (SWFDEC_IS_AS_SUPER (obj)) {
+ swfdec_as_super_replace (SWFDEC_AS_SUPER (obj), name);
+ } else if (frame->super) {
+ SwfdecAsSuper *super = SWFDEC_AS_SUPER (frame->super);
+ if (name &&
+ cx->version > 6 &&
+ swfdec_as_object_get_variable_and_flags (frame->thisp,
+ name, NULL, NULL, &super->object) &&
+ super->object == frame->thisp) {
+ super->object = super->object->prototype;
+ }
+ }
+ } else {
SWFDEC_ERROR ("no function named %s on object %s", name ? name : "unknown", obj ? G_OBJECT_TYPE_NAME(obj) : "unknown");
}
}
@@ -1313,7 +1322,7 @@ swfdec_action_start_drag (SwfdecAsContex
*swfdec_as_stack_peek (stack, 2) = *swfdec_as_stack_peek (stack, 1);
swfdec_as_object_get_variable (SWFDEC_AS_VALUE_GET_OBJECT (swfdec_as_stack_peek (stack, 2)),
SWFDEC_AS_STR_startDrag, swfdec_as_stack_peek (stack, 1));
- swfdec_action_call (cx, n_args, FALSE);
+ swfdec_action_call (cx, n_args);
/* FIXME: the return value will still be written to this position */
swfdec_as_stack_pop (stack);
}
diff --git a/libswfdec/swfdec_as_super.c b/libswfdec/swfdec_as_super.c
index c9994f9..23b5993 100644
--- a/libswfdec/swfdec_as_super.c
+++ b/libswfdec/swfdec_as_super.c
@@ -72,10 +72,14 @@ swfdec_as_super_get (SwfdecAsObject *obj
SwfdecAsSuper *super = SWFDEC_AS_SUPER (object);
if (super->object == NULL) {
- SWFDEC_WARNING ("super () called without a this object.");
+ SWFDEC_WARNING ("super.%s () called without an object.", variable);
return FALSE;
}
- if (!swfdec_as_object_get_variable (super->object->prototype, variable, val))
+ if (super->object->prototype == NULL) {
+ SWFDEC_WARNING ("super.%s () called without a prototype.", variable);
+ return FALSE;
+ }
+ if (!swfdec_as_object_get_variable_and_flags (super->object->prototype, variable, val, NULL, NULL))
return FALSE;
*flags = 0;
return TRUE;
@@ -139,3 +143,41 @@ swfdec_as_super_new (SwfdecAsFrame *fram
return ret;
}
+/**
+ * swfdec_as_super_replace:
+ * @super: the super object to replace from
+ * @function_name: garbage-collected name of the function that was called on
+ * @super or %NULL
+ *
+ * This is an internal function used to replace the current frame's super object
+ * with the next one starting from @super. (FIXME: nice explanation!) So when
+ * super.foo () has been called, a new frame is constructed and after that this
+ * function is called with @super and "foo" as @function_name.
+ **/
+void
+swfdec_as_super_replace (SwfdecAsSuper *super, const char *function_name)
+{
+ SwfdecAsSuper *replace;
+ SwfdecAsContext *context;
+
+ g_return_if_fail (SWFDEC_IS_AS_SUPER (super));
+
+ context = SWFDEC_AS_OBJECT (super)->context;
+ replace = SWFDEC_AS_SUPER (context->frame->super);
+ if (replace == NULL)
+ return;
+ if (super->object == NULL || super->object->prototype == NULL) {
+ replace->object = NULL;
+ return;
+ }
+ replace->object = super->object->prototype;
+ if (function_name && context->version > 6) {
+ SwfdecAsObject *res;
+ if (swfdec_as_object_get_variable_and_flags (replace->object,
+ function_name, NULL, NULL, &res) &&
+ replace->object != res) {
+ while (replace->object->prototype != res)
+ replace->object = replace->object->prototype;
+ }
+ }
+}
diff --git a/libswfdec/swfdec_as_super.h b/libswfdec/swfdec_as_super.h
index 1870307..117b20a 100644
--- a/libswfdec/swfdec_as_super.h
+++ b/libswfdec/swfdec_as_super.h
@@ -49,6 +49,8 @@ GType swfdec_as_super_get_type (void);
SwfdecAsObject *swfdec_as_super_new (SwfdecAsFrame * frame);
+void swfdec_as_super_replace (SwfdecAsSuper * super,
+ const char * function_name);
G_END_DECLS
#endif
diff-tree d4d1998c7e04a7651d89a2c3fb56eb90ba3d474d (from 08a077a8e233015b32d4aac2742b8374434beaad)
Author: Benjamin Otte <otte at gnome.org>
Date: Fri Jul 6 17:00:22 2007 +0100
change get_variable_and_flags to return the object with the property.
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 8f51236..96c466c 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -389,12 +389,13 @@ swfdec_as_object_set_variable (SwfdecAsO
gboolean
swfdec_as_object_get_variable_and_flags (SwfdecAsObject *object,
- const char *variable, SwfdecAsValue *value, guint *flags)
+ const char *variable, SwfdecAsValue *value, guint *flags, SwfdecAsObject **pobject)
{
SwfdecAsObjectClass *klass;
guint i;
SwfdecAsValue tmp_val;
guint tmp_flags;
+ SwfdecAsObject *tmp_pobject;
g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), FALSE);
g_return_val_if_fail (variable != NULL, FALSE);
@@ -403,20 +404,27 @@ swfdec_as_object_get_variable_and_flags
value = &tmp_val;
if (flags == NULL)
flags = &tmp_flags;
+ if (pobject == NULL)
+ pobject = &tmp_pobject;
for (i = 0; i < 256 && object != NULL; i++) {
klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
- if (klass->get (object, variable, value, flags))
+ if (klass->get (object, variable, value, flags)) {
+ *pobject = object;
return TRUE;
+ }
object = object->prototype;
}
if (i == 256) {
swfdec_as_context_abort (object->context, "Prototype recursion limit exceeded");
+ *flags = 0;
+ *pobject = NULL;
return FALSE;
}
//SWFDEC_WARNING ("no such variable %s", variable);
SWFDEC_AS_VALUE_SET_UNDEFINED (value);
*flags = 0;
+ *pobject = NULL;
return FALSE;
}
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index f6e14ed..66e919f 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -117,12 +117,13 @@ void swfdec_as_object_set_variable (Swf
const char * variable,
const SwfdecAsValue * value);
#define swfdec_as_object_get_variable(object, variable, value) \
- swfdec_as_object_get_variable_and_flags (object, variable, value, NULL)
+ swfdec_as_object_get_variable_and_flags (object, variable, value, NULL, NULL)
gboolean swfdec_as_object_get_variable_and_flags
(SwfdecAsObject * object,
const char * variable,
SwfdecAsValue * value,
- guint * flags);
+ guint * flags,
+ SwfdecAsObject ** pobject);
gboolean swfdec_as_object_delete_variable(SwfdecAsObject * object,
const char * variable);
void swfdec_as_object_set_variable_flags
diff --git a/libswfdec/swfdec_as_with.c b/libswfdec/swfdec_as_with.c
index fa02b0d..9ef6c2e 100644
--- a/libswfdec/swfdec_as_with.c
+++ b/libswfdec/swfdec_as_with.c
@@ -44,7 +44,7 @@ swfdec_as_with_get (SwfdecAsObject *obje
{
SwfdecAsWith *with = SWFDEC_AS_WITH (object);
- return swfdec_as_object_get_variable_and_flags (with->object, variable, val, flags);
+ return swfdec_as_object_get_variable_and_flags (with->object, variable, val, flags, NULL);
}
static void
More information about the Swfdec
mailing list