[pypy-svn] r15489 - in pypy/dist/pypy/rpython/memory: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Sun Jul 31 22:51:03 CEST 2005


Author: cfbolz
Date: Sun Jul 31 22:50:58 2005
New Revision: 15489

Added:
   pypy/dist/pypy/rpython/memory/lltypesimulation.py
   pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py
Modified:
   pypy/dist/pypy/rpython/memory/lladdress.py
   pypy/dist/pypy/rpython/memory/simulator.py
Log:
started writing an implementation of lltype ptrs that use the memory
simulator. It is a bit crooked and for now only Structs with primitive types.


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 22:50:58 2005
@@ -36,6 +36,13 @@
 
     def __repr__(self):
         return "<addr: %s>" % self.intaddress
+
+    def _load(self, fmt):
+        return simulator.getstruct(fmt, self.intaddress)
+
+    def _store(self, fmt, *values):
+        simulator.setstruct(fmt, self.intaddress, *values)
+
 class _accessor(object):
     def __init__(self, addr):
         self.intaddress = addr.intaddress
@@ -96,3 +103,4 @@
                           "char":      lltype.Char,
                           "address":   Address,
                           }
+

Added: pypy/dist/pypy/rpython/memory/lltypesimulation.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/memory/lltypesimulation.py	Sun Jul 31 22:50:58 2005
@@ -0,0 +1,82 @@
+from pypy.rpython.memory import lladdress
+from pypy.rpython import lltype
+
+import struct
+
+primitive_to_fmt = {lltype.Signed:   "i",
+                    lltype.Unsigned: "I",
+                    lltype.Char:     "c",
+                    }
+
+def get_layout(TYPE):
+    layout = {}
+    if isinstance(TYPE, lltype.Primitive):
+        return primitive_to_fmt[TYPE]
+    if isinstance(TYPE, lltype.Ptr):
+        return "P"
+    if isinstance(TYPE, lltype.Struct):
+        curr = 0
+        for name in TYPE._names:
+            layout[name] = curr
+            curr += get_size(TYPE._flds[name])
+        layout["_size"] = curr
+        return layout
+    else:
+        assert 0, "not yet implemented"
+
+def get_size(TYPE):
+    if isinstance(TYPE, lltype.Primitive):
+        return struct.calcsize(primitive_to_fmt[TYPE])
+    elif isinstance(TYPE, lltype.Ptr):
+        return struct.calcsize("P")
+    elif isinstance(TYPE, lltype.Struct):
+        return get_layout(TYPE)["_size"]
+    else:
+        assert 0, "not yet implemented"
+        
+# this class is intended to replace the _ptr class in lltype
+# using the memory simulator
+class SimulatorPtr(object):
+    def __init__(self, TYPE, address):
+        self.__dict__['_TYPE'] = TYPE
+        self.__dict__['_T'] = TYPE.TO
+        self.__dict__['_address'] = address
+        self.__dict__['_layout'] = get_layout(TYPE.TO)
+        self._zero_initialize()
+
+    def _zero_initialize(self):
+        size = get_size(self._T)
+        self._address._store("c" * size, *(["\x00"] * size))
+
+    def __getattr__(self, field_name):
+        if isinstance(self._T, lltype.Struct):
+            offset = self._layout[field_name]
+            if field_name in self._T._flds:
+                T = self._T._flds[field_name]
+                base = self._layout[field_name]
+                if isinstance(T, lltype.Primitive):
+                    return (self._address + offset)._load(primitive_to_fmt[T])[0]
+                else:
+                    assert 0, "not implemented"
+        raise AttributeError, ("%r instance has no field %r" % (self._T,
+                                                                field_name))
+
+    def __setattr__(self, field_name, value):
+        if isinstance(self._T, lltype.Struct):
+            if field_name in self._T._flds:
+                T = self._T._flds[field_name]
+                base = self._layout[field_name]
+                if isinstance(T, lltype.Primitive):
+                    (self._address + base)._store(primitive_to_fmt[T], value)
+                    return
+                else:
+                    assert 0, "not implemented"
+        raise AttributeError, ("%r instance has no field %r" % (self._T,
+                                                                field_name))
+
+
+# for now use the simulators raw_malloc
+def malloc(T, n=None, immortal=False):
+    size = get_size(T)
+    address = lladdress.raw_malloc(size)
+    return SimulatorPtr(lltype.Ptr(T), 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 22:50:58 2005
@@ -29,7 +29,7 @@
         assert offset >= 0
         if self.freed:
             raise MemorySimulatorError, "trying to access free memory"
-        if offset + size >= self.size:
+        if offset + size > self.size:
             raise MemorySimulatorError, "trying to access memory between blocks"
         if "u" in self.status[offset: offset+size]:
             raise MemorySimulatorError, "trying to access uninitialized memory"
@@ -39,7 +39,7 @@
         assert offset >= 0
         if self.freed:
             raise MemorySimulatorError, "trying to access free memory"
-        if offset + len(value) >= self.size:
+        if offset + len(value) > self.size:
             raise MemorySimulatorError, "trying to access memory between blocks"
         a = array.array("c")
         a.fromstring(value)
@@ -47,6 +47,7 @@
         s.fromstring("i" * len(value))
         self.memory[offset:offset + len(value)] = a
         self.status[offset:offset + len(value)] = s
+        assert len(self.memory) == self.size
 
 class MemorySimulator(object):
     def __init__(self):

Added: pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py	Sun Jul 31 22:50:58 2005
@@ -0,0 +1,35 @@
+from pypy.rpython.memory.lltypesimulation import *
+from pypy.rpython.lltype import GcStruct, Ptr, Signed, Char
+
+def test_struct():
+    S0 = GcStruct("s0", ('a', Signed), ('b', Signed), ('c', Char))
+    s0 = malloc(S0)
+    print s0
+    assert s0.a == 0
+    assert s0.b == 0
+    assert s0.c == '\x00'
+    s0.a = 42
+    s0.b = 43
+    s0.c = 'x'
+    assert s0.a == 42
+    assert s0.b == 43
+    assert s0.c == 'x'
+    s0.a = 1
+    s0.b = s0.a
+    assert s0.a == 1
+    assert s0.b == 1
+
+def DONOTtest_array():
+    Ar = lltype.GcArray(('v', Signed))
+    x = malloc(Ar,0)
+    print x
+    assert len(x) == 0
+    x = malloc(Ar,3)
+    print x
+    assert typeOf(x) == Ptr(Ar)
+    assert typeOf(x[0].v) == Signed
+    assert x[0].v == 0
+    x[0].v = 1
+    x[1].v = 2
+    x[2].v = 3
+    assert [x[z].v for z in range(3)] == [1, 2, 3]



More information about the Pypy-commit mailing list