[pypy-svn] r46096 - in pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem: . test

fijal at codespeak.net fijal at codespeak.net
Tue Aug 28 14:35:03 CEST 2007


Author: fijal
Date: Tue Aug 28 14:34:59 2007
New Revision: 46096

Modified:
   pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py
   pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/test/test_rffi.py
Log:
An experiment with custom policy to strings. Can automatically cast strings
to ll_ptrs and free them (but not the other way around yet!)

This function is getting really obscure TBH


Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py	Tue Aug 28 14:34:59 2007
@@ -28,7 +28,15 @@
 
 def llexternal(name, args, result, _callable=None, sources=[], includes=[],
                libraries=[], include_dirs=[], sandboxsafe=False,
-               canraise=False):
+               canraise=False, stringpolicy='noauto'):
+    """ String policies:
+    autocast - automatically cast to ll_string, but don't delete it
+    fullauto - automatically cast + delete is afterwards
+    noauto - don't do anything
+
+    WARNING: It's likely that in future we'll decide to use fullauto by
+             default
+    """
     ext_type = lltype.FuncType(args, result)
     if _callable is None:
         _callable = ll2ctypes.LL2CtypesCallable(ext_type)
@@ -40,21 +48,38 @@
                                  _callable=_callable,
                                  _safe_not_sandboxed=sandboxsafe,
                                  _debugexc=True, # on top of llinterp
-                                 canraise=canraise)  
+                                 canraise=canraise)
     if isinstance(_callable, ll2ctypes.LL2CtypesCallable):
         _callable.funcptr = funcptr
 
     unrolling_arg_tps = unrolling_iterable(enumerate(args))
     def wrapper(*args):
         real_args = ()
+        if stringpolicy == 'fullauto':
+            to_free = ()
         for i, tp in unrolling_arg_tps:
+            ll_str = None
             if isinstance(tp, lltype.Number):
                 real_args = real_args + (cast(tp, args[i]),)
             elif tp is lltype.Float:
                 real_args = real_args + (float(args[i]),)
+            elif tp is CCHARP and (stringpolicy == 'fullauto' or
+                     stringpolicy == 'autocast'):
+                ll_str = str2charp(args[i])
+                real_args = real_args + (ll_str,)
             else:
                 real_args = real_args + (args[i],)
-        return funcptr(*real_args)
+            if stringpolicy == 'fullauto':
+                if tp is CCHARP:
+                    to_free = to_free + (ll_str,)
+                else:
+                    to_free = to_free = (None,)
+        result = funcptr(*real_args)
+        if stringpolicy == 'fullauto':
+            for i, tp in unrolling_arg_tps:
+                if tp is CCHARP:
+                    lltype.free(to_free[i], flavor='raw')
+        return result
     wrapper._always_inline_ = True
     # for debugging, stick ll func ptr to that
     wrapper._ptr = funcptr

Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/test/test_rffi.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/test/test_rffi.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/test/test_rffi.py	Tue Aug 28 14:34:59 2007
@@ -5,7 +5,7 @@
 from pypy.rpython.lltypesystem.lltype import Signed, Ptr, Char, malloc
 from pypy.rpython.lltypesystem import lltype
 from pypy.tool.udir import udir
-from pypy.rpython.test.test_llinterp import interpret
+from pypy.rpython.test.test_llinterp import interpret, MallocMismatch
 from pypy.annotation.annrpython import RPythonAnnotator
 from pypy.rpython.rtyper import RPythonTyper
 from pypy.translator.backendopt.all import backend_optimizations
@@ -45,7 +45,8 @@
     assert xf() == 8+3
 
 def test_string():
-    z = llexternal('strlen', [CCHARP], Signed, includes=['string.h'])
+    z = llexternal('strlen', [CCHARP], Signed, includes=['string.h'],
+                   stringpolicy='noauto')
 
     def f():
         s = str2charp("xxx")
@@ -68,7 +69,8 @@
         return ret;
     }
     """)
-    z = llexternal('f', [CCHARP], CCHARP, sources=[c_source])    
+    z = llexternal('f', [CCHARP], CCHARP, sources=[c_source],
+                   stringpolicy='noauto')
 
     def f():
         s = str2charp("xxx")
@@ -331,3 +333,29 @@
     assert s == {'cast_int_to_uint': 1, 'direct_call': 1, 'cast_primitive': 2,
                  'cast_int_to_float': 1}
     
+
+def test_stringpolicy1():
+    strlen = llexternal('strlen', [CCHARP], INT, includes=['string.h'],
+                        stringpolicy='fullauto')
+    def f():
+        return strlen("Xxx")
+    assert interpret(f, [], backendopt=True) == 3
+
+def test_stringpolicy2():
+    def f():
+        return strlen("Xxx")        
+    strlen = llexternal('strlen', [CCHARP], INT,
+                        includes=['string.h'], stringpolicy='autocast')
+    py.test.raises(MallocMismatch, interpret, f, [], backendopt=True)
+
+def test_stringpolicy3():
+    strlen = llexternal('strlen', [CCHARP], INT,
+                        includes=['string.h'], stringpolicy='noauto')
+    def f():
+        ll_str = str2charp("Xxx")
+        res = strlen(ll_str)
+        lltype.free(ll_str, flavor='raw')
+        return res
+
+    assert interpret(f, [], backendopt=True) == 3
+    



More information about the Pypy-commit mailing list