[pypy-svn] r15451 - in pypy/dist/pypy: annotation rpython/memory rpython/memory/test
cfbolz at codespeak.net
cfbolz at codespeak.net
Sun Jul 31 02:19:30 CEST 2005
Author: cfbolz
Date: Sun Jul 31 02:19:27 2005
New Revision: 15451
Modified:
pypy/dist/pypy/annotation/binaryop.py
pypy/dist/pypy/rpython/memory/lladdress.py
pypy/dist/pypy/rpython/memory/simulator.py
pypy/dist/pypy/rpython/memory/test/test_address.py
pypy/dist/pypy/rpython/memory/test/test_simulator.py
Log:
continued (more or less finished) the memory simulator:
memory access is done by doing:
address.signed[offset] = value
address.signed[offset]
this will check for all sorts of errors.
Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py (original)
+++ pypy/dist/pypy/annotation/binaryop.py Sun Jul 31 02:19:27 2005
@@ -618,6 +618,14 @@
def union((s_addr1, s_addr2)):
return SomeAddress(is_null=s_addr1.is_null and s_addr2.is_null)
+ def sub((s_addr1, s_addr2)):
+ if s_addr1.is_null and s_addr2.is_null:
+ return getbookkeeper().immutablevalue(0)
+ return SomeInteger()
+
+ def is_((s_addr1, s_addr2)):
+ assert False, "comparisons with is not supported by addresses"
+
class __extend__(pairtype(SomeTypedAddressAccess, SomeTypedAddressAccess)):
def union((s_taa1, s_taa2)):
assert s_taa1.type == s_taa2.type
@@ -640,9 +648,3 @@
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/rpython/memory/lladdress.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/lladdress.py (original)
+++ pypy/dist/pypy/rpython/memory/lladdress.py Sun Jul 31 02:19:27 2005
@@ -1,4 +1,8 @@
+import struct
from pypy.rpython import lltype
+from pypy.rpython.memory.simulator import MemorySimulator
+from pypy.rpython.rarithmetic import r_uint
+
class Address(object):
def __new__(cls, intaddress=0):
@@ -14,34 +18,81 @@
def __init__(self, intaddress=0):
self.intaddress = intaddress
+ def _getintattr(self): #needed to make _accessor easy
+ return self.intaddress
+
def __add__(self, offset):
assert isinstance(offset, int)
return Address(self.intaddress + offset)
def __sub__(self, other):
if isinstance(other, int):
- return Address(self.intaddress + offset)
+ return Address(self.intaddress - other)
else:
return self.intaddress - other.intaddress
def __cmp__(self, other):
return cmp(self.intaddress, other.intaddress)
-NULL = Address()
+ def __repr__(self):
+ return "<addr: %s>" % self.intaddress
+class _accessor(object):
+ def __init__(self, addr):
+ self.intaddress = addr.intaddress
+ def __getitem__(self, offset):
+ result = simulator.getstruct(self.format,
+ self.intaddress + offset * self.size)
+ return self.convert_from(result[0])
+
+ def __setitem__(self, offset, value):
+ simulator.setstruct(self.format, self.intaddress + offset * self.size,
+ self.convert_to(value))
+
+class _signed_accessor(_accessor):
+ format = "i"
+ size = struct.calcsize("i")
+ convert_from = int
+ convert_to = int
+
+class _unsigned_accessor(_accessor):
+ format = "I"
+ size = struct.calcsize("I")
+ convert_from = r_uint
+ convert_to = long
+
+class _char_accessor(_accessor):
+ format = "c"
+ size = struct.calcsize("c")
+ convert_from = str
+ convert_to = str
+
+class _address_accessor(_accessor):
+ format = "P"
+ size = struct.calcsize("P")
+ convert_from = Address
+ convert_to = Address._getintattr
+
+Address.signed = property(_signed_accessor)
+Address.unsigned = property(_unsigned_accessor)
+Address.char = property(_char_accessor)
+Address.address = property(_address_accessor)
-supported_access_types = {"signed": lltype.Signed,
- "unsigned": lltype.Unsigned,
- "char": lltype.Char,
- "address": Address,
- }
+
+NULL = Address()
+simulator = MemorySimulator()
def raw_malloc(size):
- pass
+ return Address(simulator.malloc(size))
def raw_free(addr):
- pass
+ simulator.free(addr.intaddress)
def raw_memcopy(addr1, addr2, size):
pass
+supported_access_types = {"signed": lltype.Signed,
+ "unsigned": lltype.Unsigned,
+ "char": lltype.Char,
+ "address": Address,
+ }
Modified: pypy/dist/pypy/rpython/memory/simulator.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/simulator.py (original)
+++ pypy/dist/pypy/rpython/memory/simulator.py Sun Jul 31 02:19:27 2005
@@ -1,4 +1,5 @@
import array
+import struct
# all addresses in the simulator are just ints
@@ -18,6 +19,8 @@
self.freed = False
def free(self):
+ if self.freed:
+ raise MemorySimulatorError, "trying to free already freed memory"
self.freed = True
self.memory = None
self.status = None
@@ -44,3 +47,51 @@
s.fromstring("i" * len(value))
self.memory[offset:offset + len(value)] = a
self.status[offset:offset + len(value)] = s
+
+class MemorySimulator(object):
+ def __init__(self):
+ self.blocks = []
+ self.freememoryaddress = 4
+
+ def find_block(self, address):
+ lo = 0
+ hi = len(self.blocks)
+ while lo < hi:
+ mid = (lo + hi) // 2
+ block = self.blocks[mid]
+ if address < block.baseaddress:
+ hi = mid
+ elif address < block.baseaddress + block.size:
+ return block
+ else:
+ lo = mid
+ return self.blocks[mid]
+
+ def malloc(self, size):
+ result = self.freememoryaddress
+ self.blocks.append(MemoryBlock(result, size))
+ self.freememoryaddress += size
+ return result
+
+ def free(self, baseaddress):
+ if baseaddress == 0:
+ raise MemorySimulatorError, "trying to free NULL address"
+ block = self.find_block(baseaddress)
+ if baseaddress != block.baseaddress:
+ raise MemorySimulatorError, "trying to free address not malloc'ed"
+ block.free()
+
+ def getstruct(self, fmt, address):
+ block = self.find_block(address)
+ offset = address - block.baseaddress
+ size = struct.calcsize(fmt)
+ return struct.unpack(fmt, block.getbytes(offset, size))
+
+ def setstruct(self, fmt, address, *types):
+ block = self.find_block(address)
+ offset = address - block.baseaddress
+ block.setbytes(offset, struct.pack(fmt, *types))
+
+ def memcopy(self, address1, address2, size):
+ data = self.getstruct("c" * size, address1)
+ self.setstruct("c" * size, address2, *data)
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 Sun Jul 31 02:19:27 2005
@@ -1,10 +1,12 @@
import py
+import sys
from pypy.annotation import model as annmodel
from pypy.translator.annrpython import RPythonAnnotator
from pypy.objspace.flow import FlowObjSpace
from pypy.rpython.memory.lladdress import Address, NULL
from pypy.rpython.memory.lladdress import raw_malloc, raw_free, raw_memcopy
+from pypy.rpython.memory.simulator import MemorySimulatorError
class TestAddressAnnotation(object):
def test_null(self):
@@ -32,6 +34,7 @@
a = RPythonAnnotator()
py.test.raises(AssertionError,
a.build_types, f, [annmodel.SomeAddress(is_null=True)])
+ py.test.raises(MemorySimulatorError, f, NULL)
def test_memcopy(self):
def f(addr1, addr2):
@@ -61,11 +64,12 @@
s_false.const = False
s = a.build_types(f, [bool, bool])
assert isinstance(s, annmodel.SomeAddress)
- assert not s.is_null
+ assert not s.is_null
a = RPythonAnnotator()
s = a.build_types(f, [s_true, bool])
assert isinstance(s, annmodel.SomeAddress)
assert s.is_null
+ assert f(True, False) == NULL
a = RPythonAnnotator()
s = a.build_types(f, [s_false, bool])
assert isinstance(s, annmodel.SomeAddress)
@@ -82,13 +86,16 @@
def test_address_arithmetic(self):
def f(offset, char):
- addr = raw_malloc(offset * 2 + 1)
+ addr = raw_malloc(10000)
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)
+ assert f(0, "c") == "c"
+ assert f(123, "c") == "c"
+
def test_address_comparison(self):
def f(offset):
@@ -104,3 +111,17 @@
def test_null_is_singleton(self):
assert Address() is NULL
assert Address() is Address(0)
+
+ def test_memory_access(self):
+ addr = raw_malloc(1000)
+ addr.signed[0] = -1
+ assert addr.unsigned[0] == sys.maxint * 2 + 1
+ addr.address[0] = addr
+ assert addr.address[0] == addr
+
+ def test_pointer_arithmetic(self):
+ addr = raw_malloc(100)
+ assert addr + 10 - 10 == addr
+ addr.char[10] = "c"
+ assert (addr + 10).char[0] == "c"
+
Modified: pypy/dist/pypy/rpython/memory/test/test_simulator.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_simulator.py (original)
+++ pypy/dist/pypy/rpython/memory/test/test_simulator.py Sun Jul 31 02:19:27 2005
@@ -1,10 +1,57 @@
import py
-from pypy.rpython.memory.simulator import MemoryBlock
+from pypy.rpython.memory.simulator import *
class TestMemoryBlock(object):
def test_getsetbyte(self):
- block = MemoryBlock(1, 1000)
+ block = MemoryBlock(1, 100)
block.setbytes(1, "hello")
assert block.getbytes(1, 5) == "hello"
-
-
+ #uninitialized memory:
+ py.test.raises(MemorySimulatorError, block.getbytes, 2, 5)
+ #access over block borders:
+ py.test.raises(MemorySimulatorError, block.setbytes, 98, "long string")
+ #accessing freed memory:
+ block.free()
+ py.test.raises(MemorySimulatorError, block.getbytes, 2, 5)
+ #freeing free block:
+ py.test.raises(MemorySimulatorError, block.getbytes, 2, 5)
+
+class TestMemorySimulator(object):
+ def test_find_block(self):
+ simulator = MemorySimulator()
+ for size in [100, 100, 200, 300, 100, 50]:
+ simulator.malloc(size)
+ for address in [12, 99, 110, 190, 210, 310, 420, 450, 510, 630, 710]:
+ block = simulator.find_block(address)
+ assert block.baseaddress <= address < block.baseaddress + block.size
+
+ def test_malloc(self):
+ simulator = MemorySimulator()
+ for size in [2, 4, 8, 16, 32, 64, 128]:
+ baseaddress = simulator.malloc(size)
+ block = simulator.find_block(baseaddress)
+ assert block.size == size
+
+ def test_set_get_struct(self):
+ simulator = MemorySimulator()
+ address = simulator.malloc(100)
+ simulator.setstruct("iic", address, 1, 2, "a")
+ assert simulator.getstruct("iic", address) == (1, 2, "a")
+
+ def test_free(self):
+ simulator = MemorySimulator()
+ addr = simulator.malloc(100)
+ simulator.free(addr)
+ py.test.raises(MemorySimulatorError, simulator.free, addr)
+ py.test.raises(MemorySimulatorError, simulator.free, 0)
+
+ def test_memcopy(self):
+ simulator = MemorySimulator()
+ addr1 = simulator.malloc(1000)
+ addr2 = simulator.malloc(500)
+ simulator.setstruct("iii", addr1, 1, 2, 3)
+ simulator.memcopy(addr1, addr1 + 500, struct.calcsize("iii"))
+ simulator.memcopy(addr1 + 500, addr2, struct.calcsize("iii"))
+ assert simulator.getstruct("iii", addr1) == (1, 2, 3)
+ assert simulator.getstruct("iii", addr1 + 500) == (1, 2, 3)
+ assert simulator.getstruct("iii", addr2) == (1, 2, 3)
More information about the Pypy-commit
mailing list