[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