[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