[pypy-svn] r15427 - in pypy/dist/pypy: annotation documentation rpython/memory rpython/memory/test

cfbolz at codespeak.net cfbolz at codespeak.net
Sat Jul 30 19:55:16 CEST 2005


Author: cfbolz
Date: Sat Jul 30 19:55:06 2005
New Revision: 15427

Modified:
   pypy/dist/pypy/annotation/binaryop.py
   pypy/dist/pypy/annotation/builtin.py
   pypy/dist/pypy/annotation/model.py
   pypy/dist/pypy/annotation/unaryop.py
   pypy/dist/pypy/documentation/gc_planning.txt
   pypy/dist/pypy/rpython/memory/lladdress.py
   pypy/dist/pypy/rpython/memory/test/test_address.py
Log:
(cfbolz, pedronis):

added annotation to memory read/write using address.signed[offset]
added annotation for address arithmetic and comparisons
tests


Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py	(original)
+++ pypy/dist/pypy/annotation/binaryop.py	Sat Jul 30 19:55:06 2005
@@ -10,6 +10,7 @@
 from pypy.annotation.model import SomeTuple, SomeImpossibleValue
 from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeIterator
 from pypy.annotation.model import SomePBC, SomeSlice, SomeFloat
+from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess
 from pypy.annotation.model import unionof, UnionError, set, missing_operation, TLS
 from pypy.annotation.model import add_knowntypedata, merge_knowntypedata
 from pypy.annotation.bookkeeper import getbookkeeper
@@ -610,3 +611,38 @@
         return pair(p2, obj).union()
 
 
+#_________________________________________
+# memory addresses
+
+class __extend__(pairtype(SomeAddress, SomeAddress)):
+    def union((s_addr1, s_addr2)):
+        return SomeAddress(is_null=s_addr1.is_null and s_addr2.is_null)
+
+class __extend__(pairtype(SomeTypedAddressAccess, SomeTypedAddressAccess)):
+    def union((s_taa1, s_taa2)):
+        assert s_taa1.type == s_taa2.type
+        return s_taa1
+
+class __extend__(pairtype(SomeTypedAddressAccess, SomeInteger)):
+    def getitem((s_taa, s_int)):
+        from pypy.annotation.model import lltype_or_address_to_annotation
+        return lltype_or_address_to_annotation(s_taa.type)
+
+    def setitem((s_taa, s_int), s_value):
+        from pypy.annotation.model import annotation_to_lltype_or_address
+        assert annotation_to_lltype_or_address(s_value) is s_taa.type
+
+
+class __extend__(pairtype(SomeAddress, SomeInteger)):
+    def add((s_addr, s_int)):
+        return SomeAddress(is_null=False)
+
+    def sub((s_addr, s_int)):
+        return SomeAddress(is_null=False)
+
+class __extend__(pairtype(SomeAddress, SomeAddress)):
+    def sub((s_addr1, s_addr2)):
+        if s_addr1.is_null and s_addr2.is_null:
+            return getbookkeeper().immutablevalue(0)
+        return SomeInteger()
+        

Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py	(original)
+++ pypy/dist/pypy/annotation/builtin.py	Sat Jul 30 19:55:06 2005
@@ -351,7 +351,9 @@
 
 def raw_memcopy(s_addr1, s_addr2, s_int):
     assert isinstance(s_addr1, SomeAddress)
+    assert not s_addr1.is_null
     assert isinstance(s_addr2, SomeAddress)
+    assert not s_addr2.is_null
     assert isinstance(s_int, SomeInteger) #XXX add noneg...?
 
 BUILTIN_ANALYZERS[lladdress.raw_malloc] = raw_malloc

Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py	(original)
+++ pypy/dist/pypy/annotation/model.py	Sat Jul 30 19:55:06 2005
@@ -449,6 +449,31 @@
     def can_be_none(self):
         return False
 
+
+# The following class is used to annotate the intermediate value that
+# appears in expressions of the form:
+# addr.signed[offset] and addr.signed[offset] = value
+
+class SomeTypedAddressAccess(SomeObject):
+    def __init__(self, type):
+        self.type = type
+
+    def can_be_none(self):
+        return False
+
+def lltype_or_address_to_annotation(T):
+    from pypy.rpython.memory.lladdress import Address
+    if T is Address:
+        return SomeAddress()
+    return lltype_to_annotation(T)
+
+def annotation_to_lltype_or_address(s_ann):
+    from pypy.rpython.memory.lladdress import Address
+    if isinstance(s_ann, SomeAddress):
+        return Address
+    else:
+        return annotation_to_lltype(s_ann)
+    
 # ____________________________________________________________
 
 class UnionError(Exception):

Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py	(original)
+++ pypy/dist/pypy/annotation/unaryop.py	Sat Jul 30 19:55:06 2005
@@ -11,6 +11,7 @@
 from pypy.annotation.model import SomeTuple, SomeImpossibleValue
 from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeFloat
 from pypy.annotation.model import SomeIterator, SomePBC, new_or_old_class
+from pypy.annotation.model import SomeTypedAddressAccess, SomeAddress
 from pypy.annotation.model import unionof, set, setunion, missing_operation
 from pypy.annotation.bookkeeper import getbookkeeper, RPythonCallsSpace
 from pypy.annotation.classdef import isclassdef
@@ -493,3 +494,17 @@
 
     def is_true(p):
         return SomeBool()
+
+
+#_________________________________________
+# memory addresses
+
+from pypy.rpython.memory import lladdress
+
+class __extend__(SomeAddress):
+    def getattr(s_addr, s_attr):
+        assert s_attr.is_constant()
+        assert isinstance(s_attr, SomeString)
+        assert s_attr.const in lladdress.supported_access_types
+        return SomeTypedAddressAccess(
+            lladdress.supported_access_types[s_attr.const])

Modified: pypy/dist/pypy/documentation/gc_planning.txt
==============================================================================
--- pypy/dist/pypy/documentation/gc_planning.txt	(original)
+++ pypy/dist/pypy/documentation/gc_planning.txt	Sat Jul 30 19:55:06 2005
@@ -23,7 +23,7 @@
    - reading: addr.signed[offset]
    - writing: addr.signed[offset] = value
    - datatypes:
-       * signed, unsigned, char, address
+       * signed, unsigned, char, float(?), address
 
 
 open question / whish:

Modified: pypy/dist/pypy/rpython/memory/lladdress.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/lladdress.py	(original)
+++ pypy/dist/pypy/rpython/memory/lladdress.py	Sat Jul 30 19:55:06 2005
@@ -1,7 +1,17 @@
+from pypy.rpython import lltype
+
+
 
 class Address(object):
     pass
 
+
+supported_access_types = {"signed":    lltype.Signed,
+                          "unsigned":  lltype.Unsigned,
+                          "char":      lltype.Char,
+                          "address":   Address,
+                          }
+
 NULL = Address()
 
 def raw_malloc(size):

Modified: pypy/dist/pypy/rpython/memory/test/test_address.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_address.py	(original)
+++ pypy/dist/pypy/rpython/memory/test/test_address.py	Sat Jul 30 19:55:06 2005
@@ -27,6 +27,7 @@
             raw_free(addr)
         a = RPythonAnnotator()
         s = a.build_types(f, [annmodel.SomeAddress()]) #does not raise
+        a = RPythonAnnotator()
         py.test.raises(AssertionError,
                        a.build_types, f, [annmodel.SomeAddress(is_null=True)])
 
@@ -36,8 +37,61 @@
         a = RPythonAnnotator()
         #does not raise:
         s = a.build_types(f, [annmodel.SomeAddress(), annmodel.SomeAddress()])
+        a = RPythonAnnotator()
         py.test.raises(AssertionError, a.build_types, f,
                        [annmodel.SomeAddress(is_null=True),
                         annmodel.SomeAddress()])
 
-    
+    def test_union(self):
+        def f(x, y):
+            if y:
+                addr = NULL
+            else:
+                if x:
+                    addr = NULL
+                else:
+                    addr = raw_malloc(10)
+            return addr
+        a = RPythonAnnotator()
+        s_true = annmodel.SomeBool()
+        s_true.const = True
+        s_false = annmodel.SomeBool()
+        s_false.const = False
+        s = a.build_types(f, [bool, bool])
+        assert isinstance(s, annmodel.SomeAddress)
+        assert not s.is_null 
+        a = RPythonAnnotator()
+        s = a.build_types(f, [s_true, bool])
+        assert isinstance(s, annmodel.SomeAddress)
+        assert s.is_null
+        a = RPythonAnnotator()
+        s = a.build_types(f, [s_false, bool])
+        assert isinstance(s, annmodel.SomeAddress)
+        assert not s.is_null
+        
+    def test_memory_access(self):
+        def f(offset, value):
+            addr = raw_malloc(offset * 2 + 1)
+            addr.signed[offset] = value
+            return addr.signed[offset]
+        a = RPythonAnnotator()
+        s = a.build_types(f, [annmodel.SomeInteger(), annmodel.SomeInteger()])
+        assert isinstance(s, annmodel.SomeInteger)
+
+    def test_address_arithmetic(self):
+        def f(offset, char):
+            addr = raw_malloc(offset * 2 + 1)
+            same_offset = (addr + offset) - addr
+            addr.char[offset] = char
+            return (addr + same_offset).char[0]
+        a = RPythonAnnotator()
+        s = a.build_types(f, [annmodel.SomeInteger(), annmodel.SomeChar()])
+        assert isinstance(s, annmodel.SomeChar)
+
+    def test_address_comparison(self):
+        def f(offset):
+            return NULL < NULL + offset
+        a = RPythonAnnotator()
+        s = a.build_types(f, [annmodel.SomeInteger()])
+        a.translator.view()
+        assert isinstance(s, annmodel.SomeBool)



More information about the Pypy-commit mailing list