[pypy-svn] r23881 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem test

nik at codespeak.net nik at codespeak.net
Thu Mar 2 01:02:08 CET 2006


Author: nik
Date: Thu Mar  2 01:02:04 2006
New Revision: 23881

Modified:
   pypy/dist/pypy/rpython/lltypesystem/rpbc.py
   pypy/dist/pypy/rpython/ootypesystem/rpbc.py
   pypy/dist/pypy/rpython/rpbc.py
   pypy/dist/pypy/rpython/test/test_rpbc.py
Log:
(pedronis, nik)
made specialized functions work for ootype by factoring out an abstract
FunctionsPBCRepr. fixed a test about frozen methods that wasn't testing
what it thought it was (no _freeze_ method!). discovered by accident
a different failing tests for specialized methods with ootype, disabled
for now.


Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rpbc.py	Thu Mar  2 01:02:04 2006
@@ -11,9 +11,10 @@
 from pypy.rpython import robject
 from pypy.rpython import rtuple
 from pypy.rpython.rpbc import samesig,\
-     commonbase, allattributenames, adjust_shape, FunctionsPBCRepr, \
+     commonbase, allattributenames, adjust_shape, \
      AbstractClassesPBCRepr, AbstractMethodsPBCRepr, OverriddenFunctionPBCRepr, \
-     AbstractMultipleFrozenPBCRepr, MethodOfFrozenPBCRepr
+     AbstractMultipleFrozenPBCRepr, MethodOfFrozenPBCRepr, \
+     AbstractFunctionsPBCRepr
 from pypy.rpython.lltypesystem import rclass
 from pypy.tool.sourcetools import has_varargs
 
@@ -54,6 +55,21 @@
 
 # ____________________________________________________________
 
+class FunctionsPBCRepr(AbstractFunctionsPBCRepr):
+    """Representation selected for a PBC of function(s)."""
+
+    def setup_specfunc(self):
+        fields = []
+        for row in self.uniquerows:
+            fields.append((row.attrname, row.fntype))
+        return Ptr(Struct('specfunc', *fields))
+        
+    def create_specfunc(self):
+        return malloc(self.lowleveltype.TO, immortal=True)
+
+    def get_specfunc_row(self, llop, v, c_rowname, resulttype):
+        return llop.genop('getfield', [v, c_rowname], resulttype=resulttype)
+        
 class MethodsPBCRepr(AbstractMethodsPBCRepr):
     """Representation selected for a PBC of the form {func: classdef...}.
     It assumes that all the methods come from the same name in a base

Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py	Thu Mar  2 01:02:04 2006
@@ -1,6 +1,7 @@
 from pypy.rpython.rmodel import CanBeNull, Repr, inputconst
 from pypy.rpython.rpbc import AbstractClassesPBCRepr, AbstractMethodsPBCRepr, \
-        AbstractMultipleFrozenPBCRepr, MethodOfFrozenPBCRepr
+        AbstractMultipleFrozenPBCRepr, MethodOfFrozenPBCRepr, \
+        AbstractFunctionsPBCRepr
 from pypy.rpython.rclass import rtype_new_instance, getinstancerepr
 from pypy.rpython.rpbc import get_concrete_calltable
 from pypy.rpython import callparse
@@ -12,6 +13,22 @@
 from pypy.annotation.pairtype import pairtype
 import types
 
+
+class FunctionsPBCRepr(AbstractFunctionsPBCRepr):
+    """Representation selected for a PBC of function(s)."""
+
+    def setup_specfunc(self):
+        fields = {}
+        for row in self.uniquerows:
+            fields[row.attrname] = row.fntype
+        return ootype.Instance('specfunc', ootype.ROOT, fields)
+
+    def create_specfunc(self):
+        return ootype.new(self.lowleveltype)
+
+    def get_specfunc_row(self, llop, v, c_rowname, resulttype):
+        return llop.genop('oogetfield', [v, c_rowname], resulttype=resulttype)
+        
 class ClassesPBCRepr(AbstractClassesPBCRepr):
 
     def rtype_simple_call(self, hop):

Modified: pypy/dist/pypy/rpython/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/rpbc.py	Thu Mar  2 01:02:04 2006
@@ -26,7 +26,7 @@
                 if sample.overridden:
                     getRepr = OverriddenFunctionPBCRepr
                 else:
-                    getRepr = FunctionsPBCRepr
+                    getRepr = rtyper.type_system.rpbc.FunctionsPBCRepr
             else:
                 getRepr = getFrozenPBCRepr
         elif issubclass(kind, description.ClassDesc):
@@ -155,7 +155,7 @@
     return concretetable, uniquerows
 
 
-class FunctionsPBCRepr(CanBeNull, Repr):
+class AbstractFunctionsPBCRepr(CanBeNull, Repr):
     """Representation selected for a PBC of function(s)."""
 
     def __init__(self, rtyper, s_pbc):
@@ -177,10 +177,7 @@
                 # several functions, each with several specialized variants.
                 # each function becomes a pointer to a Struct containing
                 # pointers to its variants.
-                fields = []
-                for row in uniquerows:
-                    fields.append((row.attrname, row.fntype))
-                self.lowleveltype = Ptr(Struct('specfunc', *fields))
+                self.lowleveltype = self.setup_specfunc()
         self.funccache = {}
 
     def get_s_callable(self):
@@ -230,7 +227,7 @@
                 result = llfn   # from the loop above
             else:
                 # build a Struct with all the values collected in 'llfns'
-                result = malloc(self.lowleveltype.TO, immortal=True)
+                result = self.create_specfunc()
                 for attrname, llfn in llfns.items():
                     setattr(result, attrname, llfn)
         self.funccache[funcdesc] = result
@@ -267,7 +264,7 @@
             # 'v' is a Struct pointer, read the corresponding field
             row = self.concretetable[shape, index]
             cname = inputconst(Void, row.attrname)
-            return llop.genop('getfield', [v, cname], resulttype = row.fntype)
+            return self.get_specfunc_row(llop, v, cname, row.fntype)
 
     def get_unique_llfn(self):
         # try to build a unique low-level function.  Avoid to use
@@ -320,7 +317,7 @@
             v = hop.genop('indirect_call', vlist, resulttype = rresult)
         return hop.llops.convertvar(v, rresult, hop.r_result)
 
-class __extend__(pairtype(FunctionsPBCRepr, FunctionsPBCRepr)):
+class __extend__(pairtype(AbstractFunctionsPBCRepr, AbstractFunctionsPBCRepr)):
         def convert_from_to((r_fpbc1, r_fpbc2), v, llops):
             # this check makes sense because both source and dest repr are FunctionsPBCRepr
             if r_fpbc1.lowleveltype == r_fpbc2.lowleveltype:

Modified: pypy/dist/pypy/rpython/test/test_rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rpbc.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rpbc.py	Thu Mar  2 01:02:04 2006
@@ -967,54 +967,81 @@
             assert res.item0 == f(i)[0]
             assert res.item1 == f(i)[1]
 
-def test_multiple_specialized_functions():
-    def myadder(x, y):   # int,int->int or str,str->str
-        return x+y
-    def myfirst(x, y):   # int,int->int or str,str->str
-        return x
-    def mysecond(x, y):  # int,int->int or str,str->str
-        return y
-    myadder._annspecialcase_ = 'specialize:argtype(0)'
-    myfirst._annspecialcase_ = 'specialize:argtype(0)'
-    mysecond._annspecialcase_ = 'specialize:argtype(0)'
-    def f(i):
-        if i == 0:
-            g = myfirst
-        elif i == 1:
-            g = mysecond
-        else:
-            g = myadder
-        s = g("hel", "lo")
-        n = g(40, 2)
-        return len(s) * n
-    for i in range(3):
-        res = interpret(f, [i])
-        assert res == f(i)
-
-def test_specialized_method_of_frozen():
-    class space:
-        def __init__(self, tag):
-            self.tag = tag
-        def wrap(self, x):
-            if isinstance(x, int):
-                return self.tag + '< %d >' % x
+    def test_multiple_specialized_functions(self):
+        def myadder(x, y):   # int,int->int or str,str->str
+            return x+y
+        def myfirst(x, y):   # int,int->int or str,str->str
+            return x
+        def mysecond(x, y):  # int,int->int or str,str->str
+            return y
+        myadder._annspecialcase_ = 'specialize:argtype(0)'
+        myfirst._annspecialcase_ = 'specialize:argtype(0)'
+        mysecond._annspecialcase_ = 'specialize:argtype(0)'
+        def f(i):
+            if i == 0:
+                g = myfirst
+            elif i == 1:
+                g = mysecond
             else:
-                return self.tag + x
-        wrap._annspecialcase_ = 'specialize:argtype(1)'
-    space1 = space("tag1:")
-    space2 = space("tag2:")
-    def f(i):
-        if i == 1:
-            sp = space1
-        else:
-            sp = space2
-        w1 = sp.wrap('hello')
-        w2 = sp.wrap(42)
-        return w1 + w2
-    res = interpret(f, [1])
-    assert ''.join(res.chars) == 'tag1:hellotag1:< 42 >'
-    res = interpret(f, [0])
-    assert ''.join(res.chars) == 'tag2:hellotag2:< 42 >'
+                g = myadder
+            s = g("hel", "lo")
+            n = g(40, 2)
+            return len(s) * n
+        for i in range(3):
+            res = interpret(f, [i], type_system=self.ts)
+            assert res == f(i)
+
+    def test_specialized_method_of_frozen(self):
+        class space:
+            def _freeze_(self):
+                return True
+            def __init__(self, tag):
+                self.tag = tag
+            def wrap(self, x):
+                if isinstance(x, int):
+                    return self.tag + '< %d >' % x
+                else:
+                    return self.tag + x
+            wrap._annspecialcase_ = 'specialize:argtype(1)'
+        space1 = space("tag1:")
+        space2 = space("tag2:")
+        def f(i):
+            if i == 1:
+                sp = space1
+            else:
+                sp = space2
+            w1 = sp.wrap('hello')
+            w2 = sp.wrap(42)
+            return w1 + w2
+        res = interpret(f, [1], type_system=self.ts)
+        assert ''.join(res.chars) == 'tag1:hellotag1:< 42 >'
+        res = interpret(f, [0], type_system=self.ts)
+        assert ''.join(res.chars) == 'tag2:hellotag2:< 42 >'
+
+    def DONT_test_specialized_method(self):
+        class A:
+            def __init__(self, tag):
+                self.tag = tag
+            def wrap(self, x):
+                if isinstance(x, int):
+                    return self.tag + '< %d >' % x
+                else:
+                    return self.tag + x
+            wrap._annspecialcase_ = 'specialize:argtype(1)'
+        a1 = A("tag1:")
+        a2 = A("tag2:")
+        def f(i):
+            if i == 1:
+                sp = a1
+            else:
+                sp = a2
+            w1 = sp.wrap('hello')
+            w2 = sp.wrap(42)
+            return w1 + w2
+        res = interpret(f, [1], type_system=self.ts)
+        assert ''.join(res.chars) == 'tag1:hellotag1:< 42 >'
+        res = interpret(f, [0], type_system=self.ts)
+        assert ''.join(res.chars) == 'tag2:hellotag2:< 42 >'
 
 def test_call_from_list():
     def f0(n): return n+200



More information about the Pypy-commit mailing list