[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