[swfinterp] Add support for calling methods on objects
authorPhilipp Hagemeister <phihag@phihag.de>
Sun, 20 Jul 2014 12:49:10 +0000 (14:49 +0200)
committerPhilipp Hagemeister <phihag@phihag.de>
Sun, 20 Jul 2014 12:49:10 +0000 (14:49 +0200)
test/swftests/PrivateCall.as [new file with mode: 0644]
youtube_dl/swfinterp.py

diff --git a/test/swftests/PrivateCall.as b/test/swftests/PrivateCall.as
new file mode 100644 (file)
index 0000000..f1c110a
--- /dev/null
@@ -0,0 +1,21 @@
+// input: []
+// output: 9
+
+package {
+public class PrivateCall {
+    public static function main():int{
+       var f:OtherClass = new OtherClass();
+        return f.func();
+    }
+}
+}
+
+class OtherClass {
+       private function pf():int {
+               return 9;
+       }
+
+       public function func():int {
+               return this.pf();
+       }
+}
index 8ccb64c9d4a2b232c87450fe9648751aeb555d5b..d043c2f992ef0d9fa683d9667482f50f28a26fb4 100644 (file)
@@ -50,6 +50,17 @@ class _AVMClass_Object(object):
         return '%s#%x' % (self.avm_class.name, id(self))
 
 
+class _ScopeDict(dict):
+    def __init__(self, avm_class):
+        super(_ScopeDict, self).__init__()
+        self.avm_class = avm_class
+
+    def __repr__(self):
+        return '%s__Scope(%s)' % (
+            self.avm_class.name,
+            super(_ScopeDict, self).__repr__())
+
+
 class _AVMClass(object):
     def __init__(self, name_idx, name):
         self.name_idx = name_idx
@@ -59,17 +70,7 @@ class _AVMClass(object):
         self.methods = {}
         self.method_pyfunctions = {}
 
-        class ScopeDict(dict):
-            def __init__(self, avm_class):
-                super(ScopeDict, self).__init__()
-                self.avm_class = avm_class
-
-            def __repr__(self):
-                return '%s__Scope(%s)' % (
-                    self.avm_class.name,
-                    super(ScopeDict, self).__repr__())
-
-        self.variables = ScopeDict(self)
+        self.variables = _ScopeDict(self)
 
     def make_object(self):
         return _AVMClass_Object(self)
@@ -411,6 +412,14 @@ class SWFInterpreter(object):
                         res = func(args)
                         stack.append(res)
                         continue
+                    elif isinstance(obj, _ScopeDict):
+                        if mname in obj.avm_class.method_names:
+                            func = self.extract_function(obj.avm_class, mname)
+                            res = func(args)
+                        else:
+                            res = obj[mname]
+                        stack.append(res)
+                        continue
                     elif isinstance(obj, compat_str):
                         if mname == 'split':
                             assert len(args) == 1