Author: Ronan Lamy <[email protected]>
Branch: rffi-parser-2
Changeset: r89617:ac221fcd46ab
Date: 2017-01-16 19:20 +0000
http://bitbucket.org/pypy/pypy/changeset/ac221fcd46ab/

Log:    Add RPython compatible cts.cast()

diff --git a/pypy/module/cpyext/cparser.py b/pypy/module/cpyext/cparser.py
--- a/pypy/module/cpyext/cparser.py
+++ b/pypy/module/cpyext/cparser.py
@@ -10,6 +10,9 @@
 from rpython.rlib.rfile import FILEP
 from rpython.rtyper.lltypesystem import rffi, lltype
 from rpython.rtyper.tool import rfficache, rffi_platform
+from rpython.flowspace.model import Constant, const
+from rpython.flowspace.specialcase import register_flow_sc
+from rpython.flowspace.flowcontext import FlowingError
 
 _r_comment = re.compile(r"/\*.*?\*/|//([^\n\\]|\\.)*?$",
                         re.DOTALL | re.MULTILINE)
@@ -699,6 +702,7 @@
         self.includes = []
         self.struct_typedefs = {}
         self._handled = set()
+        self._frozen = False
         if includes is not None:
             for header in includes:
                 self.include(header)
@@ -740,8 +744,8 @@
         self.structs[obj] = struct
         if obj.fldtypes is not None:
             struct.fields = zip(
-                 obj.fldnames,
-                 [self.convert_field(field) for field in obj.fldtypes])
+                obj.fldnames,
+                [self.convert_field(field) for field in obj.fldtypes])
         return struct
 
     def convert_field(self, obj):
@@ -833,6 +837,9 @@
             result = result.TYPE
         return result
 
+    def cast(self, cdecl, value):
+        return rffi.cast(self.gettype(cdecl), value)
+
     def parse_func(self, cdecl):
         cdecl = cdecl.strip()
         if cdecl[-1] != ';':
@@ -843,6 +850,20 @@
         FUNCP = self.convert_type(tp.as_function_pointer())
         return decl.name, FUNCP.TO
 
+    def _freeze_(self):
+        if self._frozen:
+            return True
+
+        @register_flow_sc(self.cast)
+        def sc_cast(ctx, v_decl, v_arg):
+            if not isinstance(v_decl, Constant):
+                raise FlowingError(
+                    "The first argument of cts.cast() must be a constant.")
+            TP = self.gettype(v_decl.value)
+            return ctx.appcall(rffi.cast, const(TP), v_arg)
+        self._frozen = True
+        return True
+
 
 def parse_source(source, includes=None, headers=None, configure_now=True):
     cts = CTypeSpace(headers=headers, includes=includes)
diff --git a/pypy/module/cpyext/test/test_cparser.py 
b/pypy/module/cpyext/test/test_cparser.py
--- a/pypy/module/cpyext/test/test_cparser.py
+++ b/pypy/module/cpyext/test/test_cparser.py
@@ -1,3 +1,6 @@
+from rpython.flowspace.model import const
+from rpython.flowspace.objspace import build_flow
+from rpython.translator.simplify import simplify_graph
 from rpython.rtyper.lltypesystem import rffi, lltype
 from pypy.module.cpyext.cparser import parse_source, CTypeSpace
 
@@ -164,6 +167,7 @@
     cts = parse_source(decl)
     assert cts.gettype('Py_ssize_t') == rffi.SSIZE_T
     assert cts.gettype('TestFloatObject *').TO.c_ob_refcnt == rffi.SSIZE_T
+    assert cts.cast('Py_ssize_t', 42) == rffi.cast(rffi.SSIZE_T, 42)
 
 def test_parse_funcdecl():
     decl = """
@@ -185,3 +189,16 @@
     assert name == 'some_func'
     assert FUNC.RESULT == cts.gettype('func_t')
     assert FUNC.ARGS == (cts.gettype('TestFloatObject *'),)
+
+def test_translate_cast():
+    cdef = "typedef ssize_t Py_ssize_t;"
+    cts = parse_source(cdef)
+
+    def f():
+        return cts.cast('Py_ssize_t*', 0)
+    graph = build_flow(f)
+    simplify_graph(graph)
+    assert len(graph.startblock.operations) == 1
+    op = graph.startblock.operations[0]
+    assert op.args[0] == const(rffi.cast)
+    assert op.args[1].value is cts.gettype('Py_ssize_t*')
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to