[pypy-svn] r51781 - pypy/branch/unified-rtti/pypy/rpython/lltypesystem

arigo at codespeak.net arigo at codespeak.net
Fri Feb 22 11:47:42 CET 2008


Author: arigo
Date: Fri Feb 22 11:47:38 2008
New Revision: 51781

Modified:
   pypy/branch/unified-rtti/pypy/rpython/lltypesystem/llmemory.py
Log:
Forgot this in the previous check-in.


Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/llmemory.py	(original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/llmemory.py	Fri Feb 22 11:47:38 2008
@@ -439,6 +439,11 @@
     def __ge__(self, other):
         return not (self < other)
 
+    def __or__(self, other):
+        return _or_flags(self, 0, other)
+    def __and__(self, other):
+        return _and_flags(self, 0, other)
+
     def ref(self):
         if not self:
             raise NullAddressError
@@ -458,6 +463,75 @@
 
 # ____________________________________________________________
 
+class fakeaddresswithflags(object):
+    MASK = 3
+
+    def __init__(self, adr, flags):
+        assert isinstance(adr, fakeaddress)
+        assert flags != 0
+        if adr._cast_to_int() & self.MASK != 0:
+            raise ValueError("'addr | flag': the base address seems to be at "
+                             "a non-aligned memory location")
+        self.adr = adr
+        self.flags = flags
+
+    def __repr__(self):
+        return '<%r | 0x%x>' % (self.adr, self.flags)
+
+    def __eq__(self, other):
+        if isinstance(other, fakeaddresswithflags):
+            return self.adr == other.adr and self.flags == other.flags
+        if isinstance(other, fakeaddress):
+            return False
+        return NotImplemented
+
+    def __ne__(self, other):
+        if isinstance(other, fakeaddresswithflags):
+            return not (self.adr == other.adr and self.flags == other.flags)
+        if isinstance(other, fakeaddress):
+            return True
+        return NotImplemented
+
+    def __or__(self, other):
+        return _or_flags(self.adr, self.flags, other)
+
+    def __and__(self, other):
+        return _and_flags(self.adr, self.flags, other)
+
+    def _cast_to_ptr(self, EXPECTED_TYPE):
+        raise ValueError("cannot cast %r")
+
+    def _cast_to_int(self):
+        value = self.adr._cast_to_int()
+        assert value & self.MASK == 0
+        return value | self.flags
+
+def _or_flags(adr, flags1, flags2):
+    if not isinstance(flags2, int):
+        return NotImplemented
+    if not (0 <= flags2 <= fakeaddresswithflags.MASK):
+        raise ValueError("'addr | flag': can only set the lower bits, "
+                         "got flag=0x%x" % (flags2,))
+    flags = flags1 | flags2
+    if flags == 0:
+        return adr
+    else:
+        return fakeaddresswithflags(adr, flags)
+
+def _and_flags(adr, flags1, flags2):
+    if not isinstance(flags2, int):
+        return NotImplemented
+    if not (0 <= ~flags2 <= fakeaddresswithflags.MASK):
+        raise ValueError("'addr & flag': can only clear the lower bits, "
+                         "got flag=0x%x" % (flags2,))
+    flags = flags1 & flags2
+    if flags == 0:
+        return adr
+    else:
+        return fakeaddresswithflags(adr, flags)
+
+# ____________________________________________________________
+
 class NullAddressError(Exception):
     pass
 
@@ -550,6 +624,7 @@
 fakeaddress.char = property(_char_fakeaccessor)
 fakeaddress.address = property(_address_fakeaccessor)
 fakeaddress._TYPE = Address
+fakeaddresswithflags._TYPE = Address
 
 # the obtained address will not keep the object alive. e.g. if the object is
 # only reachable through an address, it might get collected



More information about the Pypy-commit mailing list