[pypy-svn] r31677 - in pypy/dist/pypy/rpython: . test

ac at codespeak.net ac at codespeak.net
Sat Aug 26 14:25:09 CEST 2006


Author: ac
Date: Sat Aug 26 14:25:09 2006
New Revision: 31677

Modified:
   pypy/dist/pypy/rpython/rbuiltin.py
   pypy/dist/pypy/rpython/rptr.py
   pypy/dist/pypy/rpython/test/test_rptr.py
Log:
(arre, pedronis)

support ll-ptr(*args) calls, with tests.



Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Sat Aug 26 14:25:09 2006
@@ -49,6 +49,42 @@
             # to it.
             return (self.__class__, self.methodname, id(self.s_self))
 
+def call_args_expand(hop, takes_kwds = True):
+    hop = hop.copy()
+    from pypy.interpreter.argument import Arguments
+    arguments = Arguments.fromshape(None, hop.args_s[1].const, # shape
+                                    range(hop.nb_args-2))
+    if arguments.w_starstararg is not None:
+        raise TyperError("**kwds call not implemented")
+    if arguments.w_stararg is not None:
+        # expand the *arg in-place -- it must be a tuple
+        from pypy.rpython.rtuple import AbstractTupleRepr
+        if arguments.w_stararg != hop.nb_args - 3:
+            raise TyperError("call pattern too complex")
+        hop.nb_args -= 1
+        v_tuple = hop.args_v.pop()
+        s_tuple = hop.args_s.pop()
+        r_tuple = hop.args_r.pop()
+        if not isinstance(r_tuple, AbstractTupleRepr):
+            raise TyperError("*arg must be a tuple")
+        for i in range(len(r_tuple.items_r)):
+            v_item = r_tuple.getitem_internal(hop.llops, v_tuple, i)
+            hop.nb_args += 1
+            hop.args_v.append(v_item)
+            hop.args_s.append(s_tuple.items[i])
+            hop.args_r.append(r_tuple.items_r[i])
+
+    kwds = arguments.kwds_w or {}
+    if not takes_kwds and kwds:
+        raise TyperError("kwds args not supported")
+    # prefix keyword arguments with 'i_'
+    kwds_i = {}
+    for key, index in kwds.items():
+        kwds_i['i_'+key] = index
+
+    return hop, kwds_i
+
+
 class BuiltinFunctionRepr(Repr):
     lowleveltype = lltype.Void
 
@@ -81,34 +117,7 @@
         # calling a built-in function with keyword arguments:
         # mostly for rpython.objectmodel.hint() and for constructing
         # rctypes structures
-        from pypy.interpreter.argument import Arguments
-        arguments = Arguments.fromshape(None, hop.args_s[1].const, # shape
-                                        range(hop.nb_args-2))
-        if arguments.w_starstararg is not None:
-            raise TyperError("**kwds call not implemented")
-        if arguments.w_stararg is not None:
-            # expand the *arg in-place -- it must be a tuple
-            from pypy.rpython.rtuple import AbstractTupleRepr
-            if arguments.w_stararg != hop.nb_args - 3:
-                raise TyperError("call pattern too complex")
-            hop.nb_args -= 1
-            v_tuple = hop.args_v.pop()
-            s_tuple = hop.args_s.pop()
-            r_tuple = hop.args_r.pop()
-            if not isinstance(r_tuple, AbstractTupleRepr):
-                raise TyperError("*arg must be a tuple")
-            for i in range(len(r_tuple.items_r)):
-                v_item = r_tuple.getitem_internal(hop.llops, v_tuple, i)
-                hop.nb_args += 1
-                hop.args_v.append(v_item)
-                hop.args_s.append(s_tuple.items[i])
-                hop.args_r.append(r_tuple.items_r[i])
-
-        kwds = arguments.kwds_w or {}
-        # prefix keyword arguments with 'i_'
-        kwds_i = {}
-        for key, index in kwds.items():
-            kwds_i['i_'+key] = index
+        hop, kwds_i = call_args_expand(hop)
 
         bltintyper = self.findbltintyper(hop.rtyper)
         hop2 = hop.copy()

Modified: pypy/dist/pypy/rpython/rptr.py
==============================================================================
--- pypy/dist/pypy/rpython/rptr.py	(original)
+++ pypy/dist/pypy/rpython/rptr.py	Sat Aug 26 14:25:09 2006
@@ -63,6 +63,11 @@
         if not isinstance(self.lowleveltype.TO, FuncType):
             raise TyperError("calling a non-function %r", self.lowleveltype.TO)
         vlist = hop.inputargs(*hop.args_r)
+        nexpected = len(self.lowleveltype.TO.ARGS)
+        nactual = len(vlist)-1
+        if nactual != nexpected: 
+            raise TyperError("argcount mismatch:  expected %d got %d" %
+                            (nexpected, nactual))
         if isinstance(vlist[0], flowmodel.Constant):
             if hasattr(vlist[0].value, 'graph'):
                 hop.llops.record_extra_call(vlist[0].value.graph)
@@ -74,6 +79,13 @@
         return hop.genop(opname, vlist,
                          resulttype = self.lowleveltype.TO.RESULT)
 
+    def rtype_call_args(self, hop):
+        from pypy.rpython.rbuiltin import call_args_expand
+        hop, _ = call_args_expand(hop, takes_kwds=False)
+        hop.swap_fst_snd_args()
+        hop.r_s_popfirstarg()
+        return self.rtype_simple_call(hop)
+        
 
 class __extend__(pairtype(PtrRepr, IntegerRepr)):
 

Modified: pypy/dist/pypy/rpython/test/test_rptr.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rptr.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rptr.py	Sat Aug 26 14:25:09 2006
@@ -1,3 +1,4 @@
+import py
 from pypy.annotation.annrpython import RPythonAnnotator
 from pypy.rpython.annlowlevel import annotate_lowlevel_helper, LowLevelAnnotatorPolicy
 from pypy.rpython.lltypesystem.lltype import *
@@ -181,3 +182,25 @@
 
     res = interpret(fn, [23])
     assert res == 23
+
+
+def test_call_ptr():
+    def f(x,y,z):
+        return x+y+z
+    FTYPE = FuncType([Signed, Signed, Signed], Signed)
+    fptr = functionptr(FTYPE, "f", _callable=f)
+
+    def g(x,y,z):
+        tot = 0
+        tot += fptr(x,y,z)
+        tot += fptr(*(x,y,z))
+        tot += fptr(x, *(x,z))
+        return tot
+
+    res = interpret(g, [1,2,4])
+    assert res == g(1,2,4)
+
+    def wrong(x,y):
+        fptr(*(x,y))
+
+    py.test.raises(TypeError, "interpret(wrong, [1, 2])")



More information about the Pypy-commit mailing list