Author: Armin Rigo <[email protected]>
Branch: cffi-1.0
Changeset: r1991:c7865fba2eeb
Date: 2015-05-12 14:11 +0200
http://bitbucket.org/cffi/cffi/changeset/c7865fba2eeb/

Log:    Getting started on 'recompiler' producing a python file for dlopen()

diff --git a/cffi/cffi_opcode.py b/cffi/cffi_opcode.py
--- a/cffi/cffi_opcode.py
+++ b/cffi/cffi_opcode.py
@@ -1,14 +1,21 @@
+import struct
 
 class CffiOp(object):
     def __init__(self, op, arg):
         self.op = op
         self.arg = arg
+
     def as_c_expr(self):
         if self.op is None:
             assert isinstance(self.arg, str)
             return '(_cffi_opcode_t)(%s)' % (self.arg,)
         classname = CLASS_NAME[self.op]
         return '_CFFI_OP(_CFFI_OP_%s, %d)' % (classname, self.arg)
+
+    def as_bytes(self):
+        assert self.op is not None
+        return struct.pack(">i", (self.arg << 8) | self.op)
+
     def __str__(self):
         classname = CLASS_NAME.get(self.op, self.op)
         return '(%s %s)' % (classname, self.arg)
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -6,6 +6,7 @@
 class Recompiler:
 
     def __init__(self, ffi, module_name):
+        assert isinstance(module_name, bytes)
         self.ffi = ffi
         self.module_name = module_name
 
@@ -118,7 +119,7 @@
         g.close()
         return lines
 
-    def write_source_to_f(self, f, preamble):
+    def write_c_source_to_f(self, f, preamble):
         self._f = f
         prnt = self._prnt
         #
@@ -264,6 +265,35 @@
         prnt('#endif')
         self.ffi._recompiler_module_name = self.module_name
 
+    def _to_py(self, x):
+        if isinstance(x, bytes):
+            r = repr(x)
+            if not r.startswith('b'):
+                r = 'b' + r
+            return r
+        raise TypeError(type(x).__name__)
+
+    def write_py_source_to_f(self, f):
+        self._f = f
+        prnt = self._prnt
+        #
+        # header
+        prnt("# auto-generated file")
+        prnt("import _cffi_backend")
+        prnt()
+        prnt("ffi = _cffi_backend.FFI(%s," % (self._to_py(self.module_name),))
+        #
+        # the '_types' keyword argument
+        self.cffi_types = tuple(self.cffi_types)    # don't change any more
+        types_lst = [op.as_bytes() for op in self.cffi_types]
+        prnt('    _types = %s,' % (self._to_py(''.join(types_lst)),))
+        typeindex2type = dict([(i, tp) for (tp, i) in self._typesdict.items()])
+        #
+        #.......
+        #
+        # the footer
+        prnt(')')
+
     # ----------
 
     def _convert_funcarg_to_c(self, tp, fromvar, tovar, errcode):
@@ -897,22 +927,32 @@
                 s = s.encode('ascii')
             super(NativeIO, self).write(s)
 
-def make_c_source(ffi, module_name, preamble, target_c_file):
+def _make_c_or_py_source(ffi, module_name, preamble, target_file):
     recompiler = Recompiler(ffi, module_name)
     recompiler.collect_type_table()
     f = NativeIO()
-    recompiler.write_source_to_f(f, preamble)
+    if preamble is not None:
+        recompiler.write_c_source_to_f(f, preamble)
+    else:
+        recompiler.write_py_source_to_f(f)
     output = f.getvalue()
     try:
-        with open(target_c_file, 'r') as f1:
+        with open(target_file, 'r') as f1:
             if f1.read(len(output) + 1) != output:
                 raise IOError
         return False     # already up-to-date
     except IOError:
-        with open(target_c_file, 'w') as f1:
+        with open(target_file, 'w') as f1:
             f1.write(output)
         return True
 
+def make_c_source(ffi, module_name, preamble, target_c_file):
+    assert preamble is not None
+    return _make_c_or_py_source(ffi, module_name, preamble, target_c_file)
+
+def make_py_source(ffi, module_name, target_py_file):
+    return _make_c_or_py_source(ffi, module_name, None, target_py_file)
+
 def _get_extension(module_name, c_file, kwds):
     source_name = ffiplatform.maybe_relative_path(c_file)
     return ffiplatform.get_extension(source_name, module_name, **kwds)
diff --git a/testing/cffi1/test_dlopen.py b/testing/cffi1/test_dlopen.py
--- a/testing/cffi1/test_dlopen.py
+++ b/testing/cffi1/test_dlopen.py
@@ -1,57 +1,18 @@
 import py
-py.test.skip("later")
+from cffi import FFI
+from cffi.recompiler import make_py_source
+from testing.udir import udir
 
-from cffi1 import FFI
-import math
 
+def test_simple():
+    ffi = FFI()
+    ffi.cdef("int close(int); static const int BB = 42;")
+    target = udir.join('test_simple.py')
+    assert make_py_source(ffi, 'test_simple', str(target))
+    assert target.read() == r"""# auto-generated file
+import _cffi_backend
 
-def test_cdef_struct():
-    ffi = FFI()
-    ffi.cdef("struct foo_s { int a, b; };")
-    assert ffi.sizeof("struct foo_s") == 8
-
-def test_cdef_union():
-    ffi = FFI()
-    ffi.cdef("union foo_s { int a, b; };")
-    assert ffi.sizeof("union foo_s") == 4
-
-def test_cdef_struct_union():
-    ffi = FFI()
-    ffi.cdef("union bar_s { int a; }; struct foo_s { int b; };")
-    assert ffi.sizeof("union bar_s") == 4
-    assert ffi.sizeof("struct foo_s") == 4
-
-def test_cdef_struct_typename_1():
-    ffi = FFI()
-    ffi.cdef("typedef struct { int a; } t1; typedef struct { t1* m; } t2;")
-    assert ffi.sizeof("t2") == ffi.sizeof("void *")
-    assert ffi.sizeof("t1") == 4
-
-def test_cdef_struct_typename_2():
-    ffi = FFI()
-    ffi.cdef("typedef struct { int a; } *p1; typedef struct { p1 m; } *p2;")
-    p2 = ffi.new("p2")
-    assert ffi.sizeof(p2[0]) == ffi.sizeof("void *")
-    assert ffi.sizeof(p2[0].m) == ffi.sizeof("void *")
-
-def test_cdef_struct_anon_1():
-    ffi = FFI()
-    ffi.cdef("typedef struct { int a; } t1; struct foo_s { t1* m; };")
-    assert ffi.sizeof("struct foo_s") == ffi.sizeof("void *")
-
-def test_cdef_struct_anon_2():
-    ffi = FFI()
-    ffi.cdef("typedef struct { int a; } *p1; struct foo_s { p1 m; };")
-    assert ffi.sizeof("struct foo_s") == ffi.sizeof("void *")
-
-def test_cdef_struct_anon_3():
-    ffi = FFI()
-    ffi.cdef("typedef struct { int a; } **pp; struct foo_s { pp m; };")
-    assert ffi.sizeof("struct foo_s") == ffi.sizeof("void *")
-
-def test_math_sin():
-    ffi = FFI()
-    ffi.cdef("double sin(double);")
-    m = ffi.dlopen('m')
-    x = m.sin(1.23)
-    assert x == math.sin(1.23)
+ffi = _cffi_backend.FFI(b'test_simple',
+    _types = b'\x00\x00\x01\r\x00\x00\x07\x01\x00\x00\x00\x0f',
+)
+"""
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to