[pypy-svn] r46371 - in pypy/dist/pypy/interpreter: . test

arigo at codespeak.net arigo at codespeak.net
Thu Sep 6 17:38:20 CEST 2007


Author: arigo
Date: Thu Sep  6 17:38:20 2007
New Revision: 46371

Modified:
   pypy/dist/pypy/interpreter/callmethod.py
   pypy/dist/pypy/interpreter/test/test_callmethod.py
Log:
An optimized version of space.call_method() based on the same principle
as the CALL_METHOD bytecode.


Modified: pypy/dist/pypy/interpreter/callmethod.py
==============================================================================
--- pypy/dist/pypy/interpreter/callmethod.py	(original)
+++ pypy/dist/pypy/interpreter/callmethod.py	Thu Sep  6 17:38:20 2007
@@ -13,6 +13,7 @@
 from pypy.interpreter import pyframe, function
 from pypy.rlib.jit import we_are_jitted
 from pypy.interpreter.argument import Arguments
+from pypy.objspace.std import StdObjSpace
 
 
 def object_getattribute(space):
@@ -68,3 +69,23 @@
         finally:
             f.dropvalues(nargs + 2)
         f.pushvalue(w_result)
+
+
+def call_method(space, w_obj, methname, *arg_w):
+    """An optimized version of space.call_method()
+    based on the same principle as above.
+    """
+    w_name = space.wrap(methname)
+    w_getattribute = space.lookup(w_obj, '__getattribute__')
+    if w_getattribute is object_getattribute(space):
+        w_descr = space.lookup(w_obj, methname)
+        if type(w_descr) is function.Function:
+            w_value = w_obj.getdictvalue_attr_is_in_class(space, w_name)
+            if w_value is None:
+                # fast method path: a function object in the class,
+                # nothing in the instance
+                return space.call_function(w_descr, w_obj, *arg_w)
+    w_meth = space.getattr(w_obj, w_name)
+    return space.call_function(w_meth, *arg_w)
+
+StdObjSpace.call_method = call_method

Modified: pypy/dist/pypy/interpreter/test/test_callmethod.py
==============================================================================
--- pypy/dist/pypy/interpreter/test/test_callmethod.py	(original)
+++ pypy/dist/pypy/interpreter/test/test_callmethod.py	Thu Sep  6 17:38:20 2007
@@ -103,3 +103,21 @@
             else:
                 raise Exception("did not raise?")
         """
+
+
+class TestCallMethod:
+
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{"objspace.opcodes.CALL_METHOD": True})
+
+    def test_space_call_method(self):
+        space = self.space
+        w_lst = space.newlist([])
+        space.call_method(w_lst, 'append', space.w_False)
+        res = space.int_w(space.call_method(w_lst, '__len__'))
+        assert res == 1
+
+    def test_fallback_case(self):
+        space = self.space
+        space.int_w(space.call_method(space.wrap(space.sys),
+                                      'getrecursionlimit'))



More information about the Pypy-commit mailing list