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