[pypy-svn] r23869 - in pypy/dist/pypy/translator/llvm: . test

rxe at codespeak.net rxe at codespeak.net
Wed Mar 1 23:17:26 CET 2006


Author: rxe
Date: Wed Mar  1 23:17:22 2006
New Revision: 23869

Added:
   pypy/dist/pypy/translator/llvm/test/test_symbolic.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/llvm/codewriter.py
   pypy/dist/pypy/translator/llvm/database.py
   pypy/dist/pypy/translator/llvm/opwriter.py
Log:
(mwh, rxe)

Added offset reprs in database and added tests for symbolic offsets.
Moved getindexhelper to a more amenable place for others to use.



Modified: pypy/dist/pypy/translator/llvm/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/codewriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/codewriter.py	Wed Mar  1 23:17:22 2006
@@ -141,6 +141,10 @@
         # ---------------
         # All global variables in LLVM are pointers, and pointers must also be
         # dereferenced with the getelementptr instruction (hence the int 0)
+
+        # not only that, but if we need to look into something (ie a struct)
+        # then we must get the initial pointer to ourself
+
         if getptr:
             indices = [(self.word_repr, 0)] + list(indices)
         res = "%(targetvar)s = getelementptr %(type)s %(typevar)s, " % locals()

Modified: pypy/dist/pypy/translator/llvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/database.py	(original)
+++ pypy/dist/pypy/translator/llvm/database.py	Wed Mar  1 23:17:22 2006
@@ -5,7 +5,7 @@
 from pypy.translator.llvm.funcnode import FuncNode, FuncTypeNode
 from pypy.translator.llvm.extfuncnode import ExternalFuncNode
 from pypy.translator.llvm.structnode import StructNode, StructVarsizeNode, \
-     StructTypeNode, StructVarsizeTypeNode
+     StructTypeNode, StructVarsizeTypeNode, getindexhelper
 from pypy.translator.llvm.arraynode import ArrayNode, StrArrayNode, \
      VoidArrayNode, ArrayTypeNode, VoidArrayTypeNode
 from pypy.translator.llvm.opaquenode import OpaqueNode, ExtOpaqueNode, \
@@ -366,10 +366,39 @@
             # XXXXX things are happening in the gc world...
             # assert value == NULL
             repr = 'null' 
+        elif isinstance(value, llmemory.AddressOffset):
+            return self.offset_str(value)
         else:
             repr = str(value)
         return repr
 
+    def offset_str(self, value):
+
+        #XXX Need to understand and doc this better
+        
+        if isinstance(value, llmemory.FieldOffset):
+            pos = getindexhelper(value.fldname, value.TYPE)
+            return "cast(%s* getelementptr(%s* null, int 0, uint %s) to int)" % (
+                self.repr_type(getattr(value.TYPE, value.fldname)),
+                self.repr_type(value.TYPE),
+                pos)
+
+        elif isinstance(value, llmemory.ItemOffset):
+            return "cast(%s* getelementptr(%s* null, int %s) to int)" % (
+                self.repr_type(value.TYPE), self.repr_type(value.TYPE), value.repeat)
+
+        elif isinstance(value, llmemory.ArrayItemsOffset):
+            return "cast(%s* getelementptr(%s* null, int 0, uint 1) to int)" % (
+                self.repr_type(value.TYPE.OF), self.repr_type(value.TYPE))
+
+        elif isinstance(value, llmemory.CompositeOffset):
+            return "cast(%s* getelementptr(%s* null, int 0, uint 1, int %s) to int)" % (
+                self.repr_type(value.second.TYPE),
+                self.repr_type(value.first.TYPE),
+                value.second.repeat)
+        else:
+            raise Exception("unsupported offset")
+        
     def get_machine_word(self):
         return self.primitives[lltype.Signed]
 

Modified: pypy/dist/pypy/translator/llvm/opwriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/opwriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/opwriter.py	Wed Mar  1 23:17:22 2006
@@ -1,6 +1,8 @@
 from pypy.objspace.flow.model import Constant
 from pypy.rpython.lltypesystem import lltype
 from pypy.translator.llvm.log import log 
+from pypy.translator.llvm.structnode import getindexhelper
+
 log = log.opwriter
 
 class OpRepr(object):
@@ -313,21 +315,11 @@
         else:
             raise NotImplementedError
 
-    def _getindexhelper(self, name, struct):
-        assert name in list(struct._names)
-
-        fieldnames = struct._names_without_voids()
-        try:
-            index = fieldnames.index(name)
-        except ValueError:
-            index = -1
-        return index
-
     def getfield(self, opr):
         op = opr.op
         if opr.rettype != "void":
-            index = self._getindexhelper(op.args[1].value,
-                                         op.args[0].concretetype.TO)
+            index = getindexhelper(op.args[1].value,
+                                   op.args[0].concretetype.TO)
             assert index != -1
             tmpvar = self._tmp()
             self.codewriter.getelementptr(tmpvar, opr.argtypes[0],
@@ -337,8 +329,8 @@
             self._skipped(opr)
  
     def getsubstruct(self, opr): 
-        index = self._getindexhelper(opr.op.args[1].value,
-                                     opr.op.args[0].concretetype.TO)
+        index = getindexhelper(opr.op.args[1].value,
+                               opr.op.args[0].concretetype.TO)
         assert opr.rettype != "void"
         self.codewriter.getelementptr(opr.retref, opr.argtypes[0], 
                                       opr.argrefs[0], [("uint", index)])        
@@ -347,8 +339,8 @@
         op = opr.op
         if opr.argtypes[2] != "void":
             tmpvar = self._tmp()
-            index = self._getindexhelper(op.args[1].value,
-                                         op.args[0].concretetype.TO)
+            index = getindexhelper(op.args[1].value,
+                                   op.args[0].concretetype.TO)
             self.codewriter.getelementptr(tmpvar, opr.argtypes[0],
                                           opr.argrefs[0], [("uint", index)])
             self.codewriter.store(opr.argtypes[2], opr.argrefs[2], tmpvar)

Added: pypy/dist/pypy/translator/llvm/test/test_symbolic.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm/test/test_symbolic.py	Wed Mar  1 23:17:22 2006
@@ -0,0 +1,90 @@
+import py
+from pypy.translator.interactive import Translation
+from pypy import conftest
+from pypy.rpython.lltypesystem import llmemory, lltype
+from pypy.rpython.memory import lladdress
+
+from pypy.translator.llvm.test.runtest import compile_function
+
+def test_offsetof():
+    STRUCT = lltype.GcStruct("s", ("x", lltype.Signed), ("y", lltype.Signed))
+    offsetx = llmemory.offsetof(STRUCT, 'x')
+    offsety = llmemory.offsetof(STRUCT, 'y')
+    def f():
+        s = lltype.malloc(STRUCT)
+        s.x = 1
+        adr = llmemory.cast_ptr_to_adr(s)
+        result = (adr + offsetx).signed[0]
+        (adr + offsety).signed[0] = 2
+        return result * 10 + s.y
+    fn = compile_function(f, [])
+    res = fn()
+    assert res == 12
+
+def test_offsetof():
+    STRUCT = lltype.GcStruct("s", ("x", lltype.Signed), ("y", lltype.Signed))
+    offsetx = llmemory.offsetof(STRUCT, 'x')
+    offsety = llmemory.offsetof(STRUCT, 'y')
+    def f():
+        s = lltype.malloc(STRUCT)
+        s.x = 1
+        adr = llmemory.cast_ptr_to_adr(s)
+        result = (adr + offsetx).signed[0]
+        (adr + offsety).signed[0] = 2
+        return result * 10 + s.y
+    fn = compile_function(f, [])
+    res = fn()
+    assert res == 12
+
+def test_sizeof_array_with_no_length():
+    py.test.skip("inprogress")
+    A = lltype.GcArray(lltype.Signed, hints={'nolength': True})
+    a = lltype.malloc(A, 5)
+    
+    arraysize = llmemory.itemoffsetof(A, 10)
+    signedsize = llmemory.sizeof(lltype.Signed)
+    def f():
+        return a[0] + arraysize-signedsize*10
+    fn = compile_function(f, [])
+    res = fn()
+    assert res == 0
+
+def test_itemoffsetof():
+    ARRAY = lltype.GcArray(lltype.Signed)
+    itemoffsets = [llmemory.itemoffsetof(ARRAY, i) for i in range(5)]
+    def f():
+        a = lltype.malloc(ARRAY, 5)
+        adr = llmemory.cast_ptr_to_adr(a)
+        result = 0
+        for i in range(5):
+            a[i] = i + 1
+        for i in range(5):
+            result = result * 10 + (adr + itemoffsets[i]).signed[0]
+        for i in range(5):
+            (adr + itemoffsets[i]).signed[0] = i
+        for i in range(5):
+            result = 10 * result + a[i]
+        return result
+    fn = compile_function(f, [])
+    res = fn()
+    assert res == 1234501234
+
+def test_sizeof_constsize_struct():
+    # _not_ a GcStruct, since we want to raw_malloc it
+    STRUCT = lltype.Struct("s", ("x", lltype.Signed), ("y", lltype.Signed))
+    STRUCTPTR = lltype.Ptr(STRUCT)
+    sizeofs = llmemory.sizeof(STRUCT)
+    offsety = llmemory.offsetof(STRUCT, 'y')
+    def f():
+        adr = lladdress.raw_malloc(sizeofs)
+        s = llmemory.cast_adr_to_ptr(adr, STRUCTPTR)
+        s.y = 5 # does not crash
+        result = (adr + offsety).signed[0] * 10 + int(offsety < sizeofs)
+        lladdress.raw_free(adr)
+        return result
+
+    fn = compile_function(f, [])
+    res = fn()
+    assert res == 51
+
+



More information about the Pypy-commit mailing list