[pypy-svn] r12795 - in pypy/dist/pypy: annotation rpython rpython/test

arigo at codespeak.net arigo at codespeak.net
Wed May 25 18:02:09 CEST 2005


Author: arigo
Date: Wed May 25 18:02:09 2005
New Revision: 12795

Modified:
   pypy/dist/pypy/annotation/builtin.py
   pypy/dist/pypy/annotation/model.py
   pypy/dist/pypy/annotation/unaryop.py
   pypy/dist/pypy/rpython/rbuiltin.py
   pypy/dist/pypy/rpython/rint.py
   pypy/dist/pypy/rpython/robject.py
   pypy/dist/pypy/rpython/rptr.py
   pypy/dist/pypy/rpython/rtyper.py
   pypy/dist/pypy/rpython/test/test_rlist.py
Log:
RTyper support for method calls.

list.append() seems to work, but it would be nice to have a real way to
check the generated flow graphs instead of just asserting that the rtyper
didn't crash and looking around a bit in pygame.



Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py	(original)
+++ pypy/dist/pypy/annotation/builtin.py	Wed May 25 18:02:09 2005
@@ -9,6 +9,7 @@
 from pypy.annotation.model import SomeList, SomeString, SomeTuple, SomeSlice
 from pypy.annotation.model import SomeUnicodeCodePoint
 from pypy.annotation.model import SomeFloat, unionof
+from pypy.annotation.model import annotation_to_lltype
 from pypy.annotation.bookkeeper import getbookkeeper
 from pypy.objspace.flow.model import Constant
 import pypy.rpython.rarithmetic
@@ -274,7 +275,12 @@
     parent_p._setfirst(candidate_p)
     return SomePtr(ll_ptrtype=lltype.typeOf(lltype.cast_parent(PtrT, candidate_p)))
 
+def typeOf(s_val):
+    lltype = annotation_to_lltype(s_val, info="in typeOf(): ")
+    return immutablevalue(lltype)
+
 BUILTIN_ANALYZERS[lltype.malloc] = malloc
 BUILTIN_ANALYZERS[lltype.cast_flags] = cast_flags
 BUILTIN_ANALYZERS[lltype.cast_parent] = cast_parent
+BUILTIN_ANALYZERS[lltype.typeOf] = typeOf
 

Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py	(original)
+++ pypy/dist/pypy/annotation/model.py	Wed May 25 18:02:09 2005
@@ -303,9 +303,10 @@
 class SomeBuiltin(SomeObject):
     "Stands for a built-in function or method with special-cased analysis."
     knowntype = BuiltinFunctionType  # == BuiltinMethodType
-    def __init__(self, analyser, s_self=None):
+    def __init__(self, analyser, s_self=None, methodname=None):
         self.analyser = analyser
         self.s_self = s_self
+        self.methodname = methodname
 
 
 class SomeImpossibleValue(SomeObject):

Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py	(original)
+++ pypy/dist/pypy/annotation/unaryop.py	Wed May 25 18:02:09 2005
@@ -102,7 +102,7 @@
     def find_method(obj, name):
         "Look for a special-case implementation for the named method."
         analyser = getattr(obj.__class__, 'method_' + name)
-        return SomeBuiltin(analyser, obj)
+        return SomeBuiltin(analyser, obj, name)
 
     def getattr(obj, s_attr):
         # get a SomeBuiltin if the SomeObject has

Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Wed May 25 18:02:09 2005
@@ -1,18 +1,40 @@
 from pypy.annotation.pairtype import pair, pairtype
-from pypy.annotation.model import SomeBuiltin
-from pypy.rpython.lltype import malloc, Void, Signed
+from pypy.annotation.model import SomeBuiltin, SomeObject
+from pypy.rpython.lltype import malloc, typeOf, Void, Signed
 from pypy.rpython.rtyper import TyperError, peek_at_result_annotation
-from pypy.rpython.rtyper import receiveconst, receive, direct_op
+from pypy.rpython.rtyper import receiveconst, receive, direct_op, convertvar
 
 
 class __extend__(SomeBuiltin):
 
+    def lowleveltype(s_blt):
+        if s_blt.s_self is None:
+            assert s_blt.is_constant()
+            return Void
+        else:
+            # methods of a known name are implemented as just their 'self'
+            assert s_blt.methodname is not None
+            return s_blt.s_self.lowleveltype()
+
     def rtype_simple_call(s_blt, *args_s):
-        if not s_blt.is_constant():
-            raise TyperError("non-constant built-in")
-        bltintyper = BUILTIN_TYPER[s_blt.const]
+        if s_blt.s_self is None:
+            if not s_blt.is_constant():
+                raise TyperError("non-constant built-in")
+            bltintyper = BUILTIN_TYPER[s_blt.const]
+        else:
+            # methods: look up the rtype_method_xxx()
+            name = 'rtype_method_' + s_blt.methodname
+            bltintyper = getattr(s_blt.s_self, name)
         return bltintyper(*args_s)
 
+
+class __extend__(pairtype(SomeBuiltin, SomeObject)):
+
+    def rtype_convert_from_to((s_blt, s_to), v):
+        if s_blt.s_self is None:
+            raise TyperError("conversion requested on a built-in function")
+        return convertvar(v, s_blt.s_self, s_to)
+
 # ____________________________________________________________
 
 def rtype_malloc(s_pbc_type, s_varlength=None):
@@ -27,7 +49,12 @@
         return direct_op('malloc_varsize', [v_type, v_varlength],
                          resulttype = s_result.lowleveltype())
 
+def rtype_typeOf(s_value):
+    s_result = peek_at_result_annotation()
+    return receiveconst(Void, s_result.const)
+
 
 BUILTIN_TYPER = {
     malloc: rtype_malloc,
+    typeOf: rtype_typeOf,
     }

Modified: pypy/dist/pypy/rpython/rint.py
==============================================================================
--- pypy/dist/pypy/rpython/rint.py	(original)
+++ pypy/dist/pypy/rpython/rint.py	Wed May 25 18:02:09 2005
@@ -1,13 +1,19 @@
 from pypy.annotation.pairtype import pair, pairtype
-from pypy.annotation.model import SomeInteger
-from pypy.rpython.lltype import Signed, Unsigned
+from pypy.annotation.model import SomeInteger, SomeBool
+from pypy.rpython.lltype import Signed, Unsigned, Bool
 from pypy.rpython.rtyper import peek_at_result_annotation, receive, direct_op
+from pypy.rpython.rtyper import TyperError
 
 
 class __extend__(pairtype(SomeInteger, SomeInteger)):
 
+    def rtype_convert_from_to((s_from, s_to), v):
+        # assume that converting between signed and unsigned doesn't need
+        # an operation for now
+        return v
+
     def rtype_add((s_int1, s_int2)):
-        if peek_at_result_annotation().unsigned:
+        if s_int1.unsigned or s_int2.unsigned:
             v_int1 = receive(Unsigned, arg=0)
             v_int2 = receive(Unsigned, arg=1)
             return direct_op('uint_add', [v_int1, v_int2], resulttype=Unsigned)
@@ -15,3 +21,25 @@
             v_int1 = receive(Signed, arg=0)
             v_int2 = receive(Signed, arg=1)
             return direct_op('int_add', [v_int1, v_int2], resulttype=Signed)
+
+    rtype_inplace_add = rtype_add
+
+    def rtype_lt((s_int1, s_int2)):
+        if s_int1.unsigned or s_int2.unsigned:
+            if not s_int1.nonneg or not s_int2.nonneg:
+                raise TyperError("comparing a signed and an unsigned number")
+            v_int1 = receive(Unsigned, arg=0)
+            v_int2 = receive(Unsigned, arg=1)
+            return direct_op('uint_lt', [v_int1, v_int2], resulttype=Bool)
+        else:
+            v_int1 = receive(Signed, arg=0)
+            v_int2 = receive(Signed, arg=1)
+            return direct_op('int_lt', [v_int1, v_int2], resulttype=Bool)
+
+
+
+class __extend__(SomeBool):
+
+    def rtype_is_true(s_bool):
+        v_bool = receive(Bool, arg=0)
+        return v_bool

Modified: pypy/dist/pypy/rpython/robject.py
==============================================================================
--- pypy/dist/pypy/rpython/robject.py	(original)
+++ pypy/dist/pypy/rpython/robject.py	Wed May 25 18:02:09 2005
@@ -3,7 +3,7 @@
 from pypy.annotation.model import SomePBC
 from pypy.rpython.lltype import PyObject, GcPtr, Void
 from pypy.rpython.rtyper import TyperError, peek_at_result_annotation
-from pypy.rpython.rtyper import receiveconst
+from pypy.rpython.rtyper import receiveconst, receive
 
 
 PyObjPtr = GcPtr(PyObject)
@@ -20,6 +20,19 @@
             else:
                 return PyObjPtr
 
+    def rtype_getattr(s_obj, s_attr):
+        if s_attr.is_constant() and isinstance(s_attr.const, str):
+            attr = s_attr.const
+            try:
+                s_obj.find_method(attr)   # just to check it is here
+            except AttributeError:
+                raise TyperError("no method %s on %r" % (attr, s_obj))
+            else:
+                # implement methods (of a known name) as just their 'self'
+                return receive(s_obj, arg=0)
+        else:
+            raise TyperError("getattr() with a non-constant attribute name")
+
 
 class __extend__(pairtype(SomeObject, SomeObject)):
 

Modified: pypy/dist/pypy/rpython/rptr.py
==============================================================================
--- pypy/dist/pypy/rpython/rptr.py	(original)
+++ pypy/dist/pypy/rpython/rptr.py	Wed May 25 18:02:09 2005
@@ -32,6 +32,12 @@
         v_value = receive(FIELD_TYPE, arg=2)
         direct_op('setfield', [v_ptr, v_attr, v_value])
 
+    def rtype_len(s_ptr):
+        v_ptr = receive(s_ptr, arg=0)
+        s_result = peek_at_result_annotation()
+        return direct_op('getarraysize', [v_ptr],
+                         resulttype = s_result.lowleveltype())
+
 
 class __extend__(pairtype(SomePtr, SomeInteger)):
 

Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py	(original)
+++ pypy/dist/pypy/rpython/rtyper.py	Wed May 25 18:02:09 2005
@@ -83,6 +83,15 @@
                 raise
 
         block.operations[:] = newops
+        # multiple renamings (v1->v2->v3->...) are possible
+        while True:
+            done = True
+            for v1, v2 in varmapping.items():
+                if v2 in varmapping:
+                    varmapping[v1] = varmapping[v2]
+                    done = False
+            if done:
+                break
         block.renamevariables(varmapping)
         self.insert_link_conversions(block)
 
@@ -103,7 +112,7 @@
                     newops = []
                     self.enter_operation(None, newops)
                     try:
-                        a1 = self.convertvar(a1, s_a1, s_a2)
+                        a1 = convertvar(a1, s_a1, s_a2)
                     finally:
                         self.leave_operation()
                     if newops and not can_insert_here:

Modified: pypy/dist/pypy/rpython/test/test_rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rlist.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rlist.py	Wed May 25 18:02:09 2005
@@ -16,7 +16,7 @@
     assert "did not crash"
 
 
-def NOT_READY_test_append():
+def test_append():
     def dummyfn():
         l = []
         l.append(5)
@@ -27,5 +27,5 @@
     t.annotate([])
     typer = RPythonTyper(t.annotator)
     typer.specialize()
-    t.view()
+    #t.view()
     assert "did not crash"



More information about the Pypy-commit mailing list