[pypy-commit] pypy llvm-translation-backend: Adopt rffi tests for the LLVM backend.

Manuel Jacob noreply at buildbot.pypy.org
Fri Aug 30 15:43:34 CEST 2013


Author: Manuel Jacob
Branch: llvm-translation-backend
Changeset: r66481:db9f17130f63
Date: 2012-05-12 12:11 +0200
http://bitbucket.org/pypy/pypy/changeset/db9f17130f63/

Log:	Adopt rffi tests for the LLVM backend.

diff --git a/pypy/translator/llvm/genllvm.py b/pypy/translator/llvm/genllvm.py
--- a/pypy/translator/llvm/genllvm.py
+++ b/pypy/translator/llvm/genllvm.py
@@ -169,10 +169,21 @@
             return 'inttoptr'
         return 'bitcast'
 
+    def __hash__(self):
+        return 257 * self.unsigned + self.bitwidth
+
+    def __eq__(self, other):
+        return (self.bitwidth == other.bitwidth and
+                self.unsigned == other.unsigned)
+
+    def __ne__(self, other):
+        return (self.bitwidth != other.bitwidth or
+                self.unsigned != other.unsigned)
+
 
 class CharType(IntegralType):
-    def __init__(self, bitwidth):
-        IntegralType.__init__(self, bitwidth, True)
+    def __init__(self, bytewidth, unsigned):
+        IntegralType.__init__(self, bytewidth, unsigned)
 
     def is_zero(self, value):
         return value is None or value == '\00'
@@ -249,8 +260,9 @@
 LLVMSigned = IntegralType(8, False)
 LLVMUnsigned = IntegralType(8, True)
 LLVMShort = IntegralType(4, False)
-LLVMChar = CharType(1)
-LLVMUniChar = CharType(4)
+LLVMChar = CharType(1, True)
+LLVMSignedChar = CharType(1, False)
+LLVMUniChar = CharType(4, True)
 LLVMBool = BoolType()
 LLVMFloat = FloatType('double', 64)
 LLVMSingleFloat = FloatType('float', 32)
@@ -330,6 +342,7 @@
             fields = database.genllvm.gcpolicy.get_gc_fields() + fields
         self.fields = fields
         self.fldnames_wo_voids = [f for t, f in fields if t is not LLVMVoid]
+        self.fldnames_voids = set(f for t, f in fields if t is LLVMVoid)
         self.varsize = fields[-1][0].varsize
         self.size_variants = {}
 
@@ -386,6 +399,8 @@
         return '{{\n{}\n}}'.format('\n'.join(tmp))
 
     def add_indices(self, gep, attr):
+        if attr.value in self.fldnames_voids:
+            raise VoidAttributeAccess
         index = self.fldnames_wo_voids.index(attr.value)
         gep.add_field_index(index)
         return self.fields[index][0]
@@ -762,6 +777,9 @@
     return ConstantRepr(database.get_type(lltype.typeOf(cov)), cov)
 
 
+class VoidAttributeAccess(Exception):
+    pass
+
 class GEP(object):
     def __init__(self, func_writer, ptr):
         self.func_writer = func_writer
@@ -853,7 +871,10 @@
             else:
                 func = getattr(self, 'op_' + opname, None)
                 if func is not None:
-                    func(opres, *opargs)
+                    try:
+                        func(opres, *opargs)
+                    except VoidAttributeAccess:
+                        pass
                 else:
                     raise NotImplementedError(op)
 
@@ -1147,6 +1168,9 @@
     def op_gc_reload_possibly_moved(self, result, v_newaddr, v_targetvar):
         pass
 
+    def op_gc_stack_bottom(self, result):
+        pass
+
     def op_keepalive(self, result, var):
         pass
 
@@ -1304,6 +1328,7 @@
             LLVMSigned: ctypes.c_long,
             LLVMUnsigned: ctypes.c_ulong,
             LLVMChar: ctypes.c_char,
+            LLVMSignedChar: ctypes.c_byte,
             LLVMUniChar: ctypes.c_wchar,
             LLVMBool: ctypes.c_bool,
             LLVMFloat: ctypes.c_double
diff --git a/pypy/translator/llvm/test/test_genllvm.py b/pypy/translator/llvm/test/test_genllvm.py
--- a/pypy/translator/llvm/test/test_genllvm.py
+++ b/pypy/translator/llvm/test/test_genllvm.py
@@ -1,10 +1,14 @@
 from cStringIO import StringIO
 import py
 from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.rpython.lltypesystem.rffi import (llexternal, CCHARP, str2charp,
+     charp2str, free_charp)
+from pypy.rpython.lltypesystem.test.test_rffi import BaseTestRffi
 from pypy.translator.backendopt.raisingop2direct_call import (
      raisingop2direct_call)
 from pypy.translator.c.test import test_typed, test_lltyped
 from pypy.translator.llvm import genllvm
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.translator.translator import TranslationContext
 
 
@@ -245,3 +249,41 @@
 class TestTypedLLVM(_LLVMMixin, test_typed.TestTypedTestCase):
     def test_hash_preservation(self):
         py.test.skip('not working yet')
+
+
+class TestLLVMRffi(BaseTestRffi, _LLVMMixin):
+    def compile(self, func, argtypes=None, backendopt=True, gcpolicy='framework'):
+        # XXX do not ignore backendopt
+        if gcpolicy != 'framework':
+            py.test.skip('gcpolicy not supported')
+        fn = self.getcompiled(func, argtypes)
+        def fn2(*args, **kwds):
+            kwds.pop('expected_extra_mallocs', None)
+            return fn(*args, **kwds)
+        return fn2
+
+    def test_string_reverse(self):
+        c_source = py.code.Source("""
+        #include <string.h>
+
+        char *f(char* arg)
+        {
+            char *ret = malloc(strlen(arg) + 1);
+            strcpy(ret, arg);
+            return ret;
+        }
+        """)
+        eci = ExternalCompilationInfo(separate_module_sources=[c_source],
+                                      post_include_bits=['char *f(char*);'])
+        z = llexternal('f', [CCHARP], CCHARP, compilation_info=eci)
+
+        def f():
+            s = str2charp("xxx")
+            l_res = z(s)
+            res = charp2str(l_res)
+            lltype.free(l_res, flavor='raw')
+            free_charp(s)
+            return len(res)
+
+        xf = self.compile(f, [], backendopt=False)
+        assert xf(expected_extra_mallocs=-1) == 3


More information about the pypy-commit mailing list