Author: Manuel Jacob
Branch: remove-remaining-smm
Changeset: r69471:153f2fa2ab59
Date: 2014-02-26 22:22 +0100
http://bitbucket.org/pypy/pypy/changeset/153f2fa2ab59/

Log:    Introduce a fast-path for interp2app when __args__ is passed through
        and the interp-level function is a method.

diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -592,6 +592,9 @@
                 elif unwrap_spec == [ObjSpace, W_Root, Arguments]:
                     self.__class__ = BuiltinCodePassThroughArguments1
                     self.func__args__ = func
+                elif unwrap_spec == [self_type, ObjSpace, Arguments]:
+                    self.__class__ = BuiltinCodePassThroughArgumentsMethod
+                    self.func__args__ = func
             else:
                 self.__class__ = globals()['BuiltinCode%d' % arity]
                 setattr(self, 'fastfunc_%d' % arity, fastfunc)
@@ -700,6 +703,27 @@
         return w_result
 
 
+class BuiltinCodePassThroughArgumentsMethod(BuiltinCodePassThroughArguments1):
+    # almost the same as BuiltinCodePassThroughArguments1 but passes w_obj
+    # first for the case when self.func__args__ is a method
+
+    def funcrun_obj(self, func, w_obj, args):
+        space = func.space
+        try:
+            w_result = self.func__args__(w_obj, space, args)
+        except DescrMismatch:
+            return args.firstarg().descr_call_mismatch(space,
+                                                  self.descrmismatch_op,
+                                                  self.descr_reqcls,
+                                                  args.prepend(w_obj))
+        except Exception, e:
+            self.handle_exception(space, e)
+            w_result = None
+        if w_result is None:
+            w_result = space.w_None
+        return w_result
+
+
 class BuiltinCode0(BuiltinCode):
     _immutable_ = True
     fast_natural_arity = 0
diff --git a/pypy/interpreter/test/test_gateway.py 
b/pypy/interpreter/test/test_gateway.py
--- a/pypy/interpreter/test/test_gateway.py
+++ b/pypy/interpreter/test/test_gateway.py
@@ -824,6 +824,28 @@
         assert len(called) == 1
         assert isinstance(called[0], argument.Arguments)
 
+    def test_pass_trough_arguments_method(self):
+        space = self.space
+
+        called = []
+
+        class W_Something(W_Root):
+            def f(self, space, __args__):
+                called.append(__args__)
+                a_w, _ = __args__.unpack()
+                return space.newtuple([space.wrap('f')]+a_w)
+
+        w_f = space.wrap(gateway.interp2app_temp(W_Something.f))
+
+        w_self = space.wrap(W_Something())
+        args = argument.Arguments(space, [space.wrap(7)])
+
+        w_res = space.call_obj_args(w_f, w_self, args)
+        assert space.is_true(space.eq(w_res, space.wrap(('f', 7))))
+
+        # white-box check for opt
+        assert called[0] is args
+
 
 class AppTestKeywordsToBuiltinSanity(object):
     def test_type(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to